Wednesday, March 29, 2017

Testing the Java EE 8 Specifications

The Java EE 8 Platform has definitely been moving along within the past couple of months.  Specifications have been releasing early draft reviews, milestones, and even final releases.  As a matter of fact, JSR-372 has just gone final, as JSF 2.3 has been released.  For more information, please see Arjan's Post.  It had the privilege to be a part of the JSR-372 expert group, and I really appreciate the opportunity to work with these experts on a specification that I use every day.

I created a Github Project entitled the Java EE 8 Playground, and it includes a Java EE application that contains a number of the latest updates to those specifications that will be part of the Java EE 8 release.  I will make an effort to update this project often so that it includes current dependencies for the specifications.  I will also try to add demos for the specifications so that it will be easy to build upon the examples.  In the current project, some of the JSF 2.3 features are used.

It is important that as a community we test and provide feedback for the Java EE 8 specifications as they are being developed.  It is in these stages that you have a voice that can make a change to an upcoming specification.  Please test, read the latest specification documents, and provide feedback to the respective JSRs.

Java EE 8 Playground Project:  https://github.com/juneau001/JavaEE8-Playground

Java EE 8 JSRs:

JSR 365 (CDI 2.0):  https://www.jcp.org/en/jsr/detail?id=365
JSR 366 (Java EE 8):  https://www.jcp.org/en/jsr/detail?id=366
JSR 367 (JSON Binding):  https://www.jcp.org/en/jsr/detail?id=367
JSR 369 (Servlet 4.0):  https://www.jcp.org/en/jsr/detail?id=369
JSR 370 (JAX-RS 2.1):  https://www.jcp.org/en/jsr/detail?id=370
JSR 372 (JSF 2.3 - FINAL):  https://www.jcp.org/en/jsr/detail?id=372
JSR 374 (JSON  Processing 1.1):  https://www.jcp.org/en/jsr/detail?id=374
JSR 375 (Java EE Security 1.0):  https://www.jcp.org/en/jsr/detail?id=375
JSR 380 (Bean Validation 2.0):  https://www.jcp.org/en/jsr/detail?id=380

JSR 371 (MVC - No longer officially part of Java EE 8):  https://www.jcp.org/en/jsr/detail?id=371




Saturday, March 04, 2017

JSR 365 Update: Digging Into CDI 2.0

Contexts and Dependency Injection 2.0 (JSR 365), is an update to CDI 1.2, which is currently part of the Java EE 7 platform.  It is currently in Public Review stage.  For those of you who are not very familiar with CDI, it defines a powerful set of complimentary services that act as a gel that help to improve the coordination and structure of application code.  For more details, please visit the specification page.

CDI 2.0 expands the usability of the Contexts and Dependency Injection services to Java SE as well, as it will now target both the Java SE and Java EE platforms.  The CDI specification has been organized into 3 parts, Part I - Core CDI, Part II - CDI in Java SE, and Part III - CDI in Java EE.  The major changes for CDI 2.0 are as follows:

  • Better alignment with Java SE 8
  • API for booting CDI within a Java SE application
  • Ability to provide observer ordering
  • Ability to fire asynchronous events
  • New Configurators Interfaces for Service Provider Interface (SPI) elements
  • Ability to configure or veto an observer method in ProcessObserverEvent event
  • Support for inline instantiation of specific annotation types
  • Addition of the InterceptionFactory interface,  which allows to create a wrapper instance whose method invocations are intercepted by method interceptors and forwarded to a provided instance.
I encourage you to take a look at the CDI 2.0 Public Review Draft for more details on the specifics of each enhancement listed, as well as a complete listing of new features.  Read through the draft and provide feedback to the expert group.  All of the pertinent details for providing feedback can be found on the JSR 365 page.  To get started testing, create a new maven based Java EE application in your favorite IDE, and add the following dependencies:

<dependency>
    <groupid>javax.enterprise</groupid>
    <artifactid>cdi-api</artifactid>
    <version>2.0-PFD</version>
</dependency>
<dependency>
    <groupid>org.jboss.weld</groupid>
    <artifactid>weld-core-bom</artifactid>
    <version>3.0.0.Alpha14</version>
    <type>pom</type>
</dependency>

In this post, we will dig into one of the new features to get you started working with the API.  Let's take a look at asynchronous events.  Until CDI 2.0,  events could only be fired in a synchronous manner.  They've been enhanced in this latest iteration for asynchronous processing.  Here's how it works:

Create an event of some type.  Next, fire the event in an asynchronous manner, and handle accordingly once the event is complete.  In this example, I have created a MovieEvent class, which will be utilized whenever a persist event occurs for a Movie object.  The MovieEvent class is as follows:

public class MovieEvent {
    
    private String message;
    private Movie movie;
    
    public MovieEvent(String message, Movie movie){
        this.message = message;
        this.movie = movie;
    }
    
    public String getMessage(){
        return this.message;
    }
    
    public void setMessage(String message){
        this.message = message;
    }
    
    public Movie getMovie(){
        return this.movie;
    }
    
    public void setMovie(Movie movie){
        this.movie = movie;
    }
    
}

In the following scenario, we are firing an event when a new Movie is persisted.  The following code resides within a MovieController CDI bean of an example JSF application:

@Named("movieController")
@SessionScoped
public class MovieController implements Serializable {

    @EJB
    private com.mycompany.cditest.session.MovieFacade ejbFacade;
    private List items = null;
    private Movie selected;
    
    @Inject
    Event<MovieEvent> movieEvents;
. . .
   private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    getFacade().edit(selected);
                    movieEvents.fireAsync(new MovieEvent("New Movie Released", selected))
                            .whenComplete((event, throwable) -> {
                                if(throwable != null){
                                    System.out.println("Error has occurred: " + throwable.getMessage());
                                } else {
                                    System.out.println("Successful Movie Processing...");
                                }
                            });
                } else {
                    getFacade().remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
. . .

When the event is fired, it creates a new MovieEvent object, and if it successfully completes then a message is printed to indicate success.  In this example, a stream is used to process the "whenComplete" action.

Feel free to clone the repository located at https://github.com/juneau001/CdiTest and take CDI 2.0 test for a spin.  This example is just one simple test of CDI 2.0.  You can clone and utilize this test project as a starting point to work with other aspects of the specification.  Keep an eye on JSR 365, which is currently in the Public Review Ballot stages.