JEE : Using EJB and Context annotations in a JAX-RS Provider class

A lot of new annotations have been introduced since the JEE6 spec. Before we had EJBs and servlets to cover most of our server-side objects in a JEE application. But in JEE6, CDI and JAX-RS have been added, along with a few other JSRs that are implemented using annotations. This results in a long list of annotations, where – in my opinion – it is not always clear which one to use, nor to understand how they work together.

In this blog, I would like to show you how EJB and CDI work or don’t work together, in combination with a JAX-RS Resource.

JAX-RS is used for writing REST-services. It allows you to create these services, simply by annotating a Java class.

This is our REST service class aka “resource class”. It will create a REST service on the /test url, an it returns a String. Here, for test purposes, we always generate a RuntimeException.


@Path("/test")
public class TestResource {
@GET
public String getCustomer() {
if (1==1) throw new RuntimeException("Whoops, something goes wrong");

return "Customer ABC";
}
}

Because we don’t want to send a stack trace to the client, but a meaningful response in the form of an Error class, we use a provider class and annotate it with @Provider (javax.ws.rs.ext.Provider). This annotation is part of the JAX-RS spec.

Annotating a class with @Provider – according to the API-documentation – “marks an implementation of an extension interface that should be discoverable by JAX-RS runtime during a provider scanning phase.”

Our provider class will catch any exception thrown by the resource class, and send a proper response object to the client instead.

The returned Error class, that will be marshalled to an xml object and returned to the client :

@XmlRootElement

public class Error {
private String desc;
public Error() {
super();
}

public Error(String desc) {
super();
this.desc = desc;
}

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

}

The provider class that will catch any exception and return the error class looks like :


@Provider

public class GenericExceptionMapper implements ExceptionMapper<Exception> {

@Context HttpServletRequest httpRequest;

public Response toResponse(Exception ex) {
return Response.status(500).entity(new Error("Error during call with method : "+httpRequest.getMethod())).build();

}

}

As you can, see, we use the @Context annotation to access the current http request. When an exception is thrown by the resource class, it will automatically be handled by the toResponse method of our provider class. It returns a response, containing the Error class, that will be sent to the client in xml format. This is done by the JAX-RS framework.

Now we have an EJB bean that we want to use in order to log this error to a database, before sending the response. So we will add this to the provider class as follows :


@Stateless

@Provider

public class GenericExceptionMapper implements ExceptionMapper<Exception> {

@Context HttpServletRequest httpRequest;

@EJB ErrorEJB errorEJB;

public Response toResponse(Exception ex) {
// log the error to the database
errorEJB.logError(ex));
// return the response
return Response.status(500)
.entity(new Error("Error during call with method : "+httpRequest.getMethod()))
.build();
}

We made the GenericExceptionMapper a stateless bean using @Stateless, in order to be able to inject the ErrorEJB into the provider.

But now, we will get a NullPointerException on the httpRequest.getMethod, as the @Context annotation won’t work  anymore.

This is because, before our update, we only used the @Provider annotation , so this class was a CDI bean. With CDI, the container looks up the injected classes in a “scope”, which will basically be a hashmap that exists for a specific period of time :

  • @RequestScoped : per request
  • @SessionScoped : per HTTP session
  • @ApplicationScoped : per application

Into that environment we can inject the HttpServletRequest using the @Context annotation

By adding the @Statefull annotation, we made an EJB from our CDI bean.

With EJBs, the container looks also into a hashmap, but checks if the bean is of type @Stateful, @Stateless or @Singleton. So it isn’t aware of any http context.

In order to solve this problem, we will inject the our ErrorEJB as CDI bean iso an EJB.

This can be done as follows :

  • replace the @Stateless by @RequestScoped
  • replace @EJB by @Inject
  • adding an empty beans.xml file to the WEB-INF

Which gives us :


@RequestScoped

@Provider

public class GenericExceptionMapper implements ExceptionMapper<Exception> {

@Context HttpServletRequest httpRequest;

@Inject ErrorEJB errorEJB;

public Response toResponse(Exception ex) {

errorEJB.logError(ex));

return Response.status(500)
.entity(new Error("Error during call with method : "+httpRequest.getMethod()))
.build();

}

Now for JEE7, there are even more annotations available, so make sure to check the docs before using them.

A JavaFX 8 Stock Ticker application

Since Java SE 7, update 6 , JavaFX is part of the Java SE, it is officially replacing Swing as Oracle’s UI library for Java, and it runs on (any) desktop, mobile, and within the browser (applet). Java SE 7 includes version JavaFX 2.2, Java SE 8 includes JavaFX8, i.e. the version we will use here.

In this blog, I would like to demonstrate how to create a simple stock ticker, written in JavaFX. Data will be fetched by calling a REST service from http://dev.markitondemand.com/#stockquote.
The url for the REST service returning the stockprice :

http://dev.markitondemand.com/Api/v2/Quote?symbol=GE

Where ‘GE’ is the symbol of the company.

Let’s start with some Eclipse setup first.

  1. install the e(fx)clipse plugin from following update site : http://download.eclipse.org/efxclipse/updates-released/1.0.0/site
  2. install the Scene Builder that will be used to design the screen. The Scene Builder is a piece of software that will help you create *.FXML files. These are plain xml files that contain the layout of your screen.
    http://www.oracle.com/technetwork/java/javase/downloads/sb2download-2177776.html is the one I used
    but newer versions can be downloaded from http://gluonhq.com/products/downloads/
  3. Install a JDK SE 8

So now we are ready to go. Open Eclipse and select ‘File’ -> ‘New’ -> ‘JavaFX Project’

selectproject

Enter a project name: StockTicker, set the JRE to a Java 8 install, and click finish.

createproject

A JavaFX project is created with a Main.java class. Right click the project , select Run As , Java Application, and you will see an empty window popping up. This shows that all components were correctly installed.

Our application contains a screen with a combo box, where we can select a company. After selection it will be added to a list view, where we can see its stock price update every 3 seconds. (If there is any trading activity of course : for more detail see http://www.batstrading.com/support/hours/ )

The Layout

In JavaFX we can create our UI in plain Java code or using .FXML files. We’ll use the latter here, as it creates a clean separation between the view and the model.

Right click the project -> New -> Other -> Package. Then enter the popup as shown below and click finish :

packageproject

Then right click the package -> New -> Other -> New FXML Document

fxmlproject

Click Next, enter ‘MainUI’ in the name of the fxml file.
Leave the Root Element as BorderPane. This is a layout with 5 areas : top,bottom, left and right. Click finish.

fxmlfileproject

A MainUI.fxml file is created. Replace the content by the following :

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane prefHeight="500.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <top>
      <Label text="Stock Ticker BATS Exchange" textAlignment="CENTER" BorderPane.alignment="CENTER">
         <font>
            <Font name="Arial" size="33.0" />
         </font>
      </Label>
   </top>
   <center>
      <VBox BorderPane.alignment="CENTER">
         <children>
            <ComboBox fx:id="cbQuote" prefHeight="20.0" prefWidth="350.0" promptText="Select a company">
               <VBox.margin>
                  <Insets bottom="20.0" left="75.0" top="20.0" />
               </VBox.margin></ComboBox>
            <TableView fx:id="listQuote" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
              <columns>
                <TableColumn fx:id="symbolCol" prefWidth="75.0" text="Symbol" />
                <TableColumn fx:id="companyCol" prefWidth="241.0" text="Company" />
                <TableColumn fx:id="lastpriceCol" prefWidth="153.0" text="Last Price" />
              </columns>
            </TableView>
         </children>
      </VBox>
   </center>
</BorderPane>

This XML already contains some links to code we will add later in the MainController.java class.
Save the .fxml file, right click the file and select ‘Open with Scene Builder’
The Scene Builder will start up and display the following screen :

scene1

Important here, is the Hierarchy block at the bottom left of the screen. It shows the structure of the layouts and components on the screen. We will use a BorderPane as the root layout, where a Label is added in the top area to use as a title. In the center area of the border pane, a VBox is added, containing a Combo Box (for selecting the quotes) and a TableView to view the quotes.

The Application

Now that we got the layout in place, we’ll start coding.
First of all, you can remove the generate package ‘application’ with its contents. It was generated by default by Eclipse, but we won’t be using it anymore.
Next step : create a new java class in the eu.iadvise.stockticker package, and call it MainApp.java. Use the following code :

public class MainApp extends Application {

	private Stage primaryStage;
    private BorderPane rootLayout;

    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("BATS Ticker Application");
        FXMLLoader loader = null;
        try {
            // Load the root layout from the fxml file
            loader = new FXMLLoader(MainApp.class.getResource("MainUI.fxml"));
            rootLayout = (BorderPane) loader.load();
        } catch (Exception e) {
            // Exception gets thrown if the fxml file could not be loaded
        	System.out.println("FXML NOT LOADED !!!!!");
            e.printStackTrace();
        }
        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

	public static void main(String[] args) {
		launch(args);
	}
}

This is our primary class, where, first we set the title of the application window, then, we load the fxml that is used as layout, and then, we launch our application. By now our package explorer should look like this :

packagelayout

When you right click ‘StockTicker’ -> Run As -> Java Application, the application should be launched and will look like this :

firstscreen

 

The code for the REST call

Before we continue with the JavaFX components, we will create the necessary classes to execute the REST call, that picks up the stock quotes.

First, we create a Company class that will be used to populate the combo box.

public class Company {

	private String symbol;
	private String name;

	public Company(String symbol, String name) {
		super();
		this.symbol = symbol;
		this.name = name;
	}
	public String getSymbol() {
		return symbol;
	}
	public String getName() {
		return name;
	}

	// This method returns the value that is shown in the combobox.
	public String toString() {
		return this.name;
	}

	public static List<Company> getListCompanies() {
		List<Company> list = new ArrayList<Company>();
		list.add(new Company("SIRI","SIRIUS XM HLDGS INC COM"));
		list.add(new Company("ABX","BARRICK GOLD CORP COM"));
		list.add(new Company("GE","GENERAL ELECTRIC CO COM"));
		list.add(new Company("TLM","TALISMAN ENERGY INC COM"));
		list.add(new Company("AAPL","APPLE INC COM"));
		list.add(new Company("SPLS","STAPLES INC COM"));
		list.add(new Company("MSFT","MICROSOFT CORP COM"));
		list.add(new Company("PFE","PFIZER INC COM"));
		list.add(new Company("ORCL","ORACLE CORP."));
		list.add(new Company("BAC","BANK AMER CORP COM"));
		list.add(new Company("XOM","EXXON MOBIL CORP COM"));
		list.add(new Company("AA","ALCOA INC COM"));
		list.add(new Company("KO","COCA COLA CO COM"));
		list.add(new Company("C","CITIGROUP INC COM NEW"));
		return list;
	}
}

The getStockQuote method will execute the REST call to fetch the stock prices. Therefore we added the jersey-bundle-1.18.jar that contains all the necessary JAX-RS class to execute the call. Get this jar from : http://repo1.maven.org/maven2/com/sun/jersey/jersey-bundle/1.18/jersey-bundle-1.18.jar and add it to the project’s build path.

To get the result from the REST call we create the StockQuote class. This is basically just a value object. :

@XmlRootElement(name="StockQuote")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class StockQuote {

	private String name; //		Name of the company
	private String symbol; //		The company's ticker symbol
	private double lastPrice;//		The last price of the company's stock

	public String getSymbol() {
		return this.symbol;
	}

	public String getName() {
		return this.name;
	}

	public double getLastPrice() {
		return this.lastPrice;
	}

	@XmlElement(name="Name")
	public void setName(String name) {
		this.name = name;
	}

	@XmlElement(name="Symbol")
	public void setSymbol(String symbol) {
		this.symbol = symbol;
	}

	@XmlElement(name="LastPrice")
	public void setLastPrice(double lastPrice) {
		this.lastPrice = lastPrice;
	}

	@Override
	public String toString() {
		return "StockQuote [name=" + name + ", symbol=" + symbol
				+ ", lastPrice=" + lastPrice + "]";
	}

}

Finally, we need to add the stock quote class that will be used in the observable list. :

public class StockQuoteOL {

	private StringProperty symbol; //	Name of the company
	private StringProperty name; //	Name of the company
	private DoubleProperty lastPrice;//	The last price of the company's stock

	public StockQuoteOL(String symbol, String name, Double lastPrice) {
		super();
		this.symbol = new SimpleStringProperty(symbol);
		this.name = new SimpleStringProperty(name);
		this.lastPrice = new SimpleDoubleProperty(lastPrice);
	}

	public StringProperty getSymbol() {
		return symbol;
	}

	public void setSymbol(StringProperty symbol) {
		this.symbol = symbol;
	}

	public StringProperty getName() {
		return name;
	}

	public void setName(StringProperty name) {
		this.name = name;
	}

	public DoubleProperty getLastPrice() {
		return lastPrice;
	}

	public void setLastPrice(DoubleProperty lastPrice) {
		this.lastPrice = lastPrice;
	}

}

The StringProperty and DoubleProperty var’s will cause the components to update if the values of these variables are updated.

The JavaFX code

For each fxml in JavaFX, we create a controller class that contains the code handling all UI actions. So we create a MainController.java class with the following content :

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.util.Duration;

import javax.ws.rs.core.MediaType;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;

public class MainController {

    @FXML
    private ComboBox<Company> cbQuote;

    @FXML
    private TableView<StockQuoteOL> listQuote;
    private ObservableList<StockQuoteOL> listQuoteObservable = FXCollections.observableArrayList();
    @FXML
    private TableColumn<StockQuoteOL, String> symbolCol;
    @FXML
    private TableColumn<StockQuoteOL, String> companyCol;
    @FXML
    private TableColumn<StockQuoteOL, Number> lastpriceCol;    

    private ScheduledService<ObservableList<StockQuoteOL>> service;
    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    public void initialize () {
        // fill up combobox with a list of companies
    	ObservableList<Company> listCompaniesObservable = FXCollections.observableArrayList();
    	listCompaniesObservable.addAll(Company.getListCompanies());
    	cbQuote.setItems(listCompaniesObservable);
        // add a change listener on the combobox
    	cbQuote.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Company>() {
	    	@Override
			public void changed(ObservableValue<? extends Company> observable,
					Company oldValue, Company newValue) {
	    			StockQuote stockQuote = getStockQuote(newValue.getSymbol());
	    			listQuoteObservable.add(new StockQuoteOL(stockQuote.getSymbol(),
	    					stockQuote.getName(),
	    					stockQuote.getLastPrice()) );
				}
	    	});
        // configure the listView with the stock quotes
    	listQuote.setItems(listQuoteObservable);
    	symbolCol.setCellValueFactory(cellData -> cellData.getValue().getSymbol());
    	companyCol.setCellValueFactory(cellData -> cellData.getValue().getName());
    	lastpriceCol.setCellValueFactory(cellData -> cellData.getValue().getLastPrice());
        // define the service to fetch the stock quotes
    	service = new PollingService(listQuoteObservable);
	    service.maximumFailureCountProperty().set(5);
	    service.setPeriod(Duration.seconds(3));
	    service.setOnFailed(new EventHandler<WorkerStateEvent>() {
	    	@Override
	    	public void handle(WorkerStateEvent event) {
	    		event.getSource().getException().printStackTrace();
	    		System.out.println(" Error in call : "+event.getSource().getException().getMessage());
	    	}
	    });
            // start the service that will run every 3 seconds
	    service.start();

    }

    class PollingService extends ScheduledService<ObservableList<StockQuoteOL>> {
    	private ObservableList<StockQuoteOL> listStockQuotes;
    	public PollingService(ObservableList<StockQuoteOL> listStockQuotes) {
    		this.listStockQuotes=listStockQuotes;
    	}
    	@Override
    	protected Task<ObservableList<StockQuoteOL>> createTask() {
    		return new PollingTask(listStockQuotes);
    	}
    }

    public class PollingTask extends Task<ObservableList<StockQuoteOL>> {
    	private ObservableList<StockQuoteOL> listStocks;
    		public PollingTask(ObservableList<StockQuoteOL> listStocks) {
    			this.listStocks = listStocks;
    		}
            @Override public ObservableList<StockQuoteOL> call() throws InterruptedException {
            	for (StockQuoteOL quote : listStocks) {
            		quote.getLastPrice().set(getStockQuote(quote.getSymbol().get()).getLastPrice());
            	}
            	return listStocks;
            }
    }

    public static StockQuote getStockQuote(String symbol) {
        Client c = Client.create();
        WebResource r = c.resource("http://dev.markitondemand.com/Api/v2/Quote?symbol="+symbol);
        ClientResponse response = r.accept( MediaType.APPLICATION_XML_TYPE).get(ClientResponse.class);
		StockQuote stockQuote =  response.getEntity(new GenericType<StockQuote>() {});
		System.out.println("Result REST call:"+stockQuote);
		return stockQuote;
    }   

}

This controller class contains the code for our MainUI.fxml layout.

To add this controller, open the MainUI.fxml in the scene builder, open the Controller section in the Document section, and select this class from the dropdown. (the eclipse plugin adds all possible controllers to this list)

controller

 

Remark : after updating and saving the .fxml file using the scene builder, make sure you refresh (F5) the file in Eclipse, otherwise the changes will not be picked up.

The member variables of the controller class, annotated with @FXML, refer to components in the .fxml file, defined with ‘fx:id’. Eg. : open the fxml in scene builder and select the combobox. in the Code section, you see the name of the member in the fx:id : cbQuote.

fxmlannot

Now we have our layout and the components, and the bindings between these components and the member variables in the controller class in place. The next step is to add functionality to the components.

In the initialize() method is executed on startup, and contains code for :

  • fill the combobox with a company list
  • add change listener on the combo box and add company
  • configuration of the list view for the stock quotes
  • definition of the service to fetch the stock quotes
  • Connect observable lists to our listview :
    cbQuote.setItems(listCompaniesObservable);
    listQuote.setItems(listQuoteObservable);
    Any changes (adding or updating of objects) in the observable list will now immediatly result in an update in the component.

As JavaFX runs in 1 thread, we will have to execute the REST service call to fetch the stock prices in a seperate thread, otherwise, the main UI would freeze during the call.

JavaFX has a few classes in the javafx.concurrent.* package that can be used to tackle this problem.

We wrote an extension on the ‘ScheduledService’ class : PollingService.java. This class executes a Task with any given time between the calls. Our Task (PollingTask.java) will fetch new prices for every company that is currently present in the listview. The service as a few methods for configuration purposes :

  • service.maximumFailureCountProperty().set(5) : After 5 failed calls, the service will stop
  • service.setPeriod(Duration.seconds(3)) : The service will be executed every 3 seconds.
  • service.setOnFailed : Callback method if the service fails. (There are more methods available like onSucceed,…)

The service.start() will eventually start the service.

Running the project

Right click the project an select Run as… Java Application.

BATS_Ticker_Application

Remember, if there is no trading at this moment, the prices will not change of course…

 

Java 8 and Spring 4

On March 27, 2014, the Spring community was happy to announce the Spring Framework 4.0.3. The reason why is that it was the first release of the Spring Framework with Java 8 support. Since then, the Spring team worked very hard to provide major updates for the Spring Framework to be even more supportive towards Java 8. As of September 4, 2014, the Spring Framework 4.1 has arrived with even more support towards the Java community.

Lambda support in Spring 4.0

A good example to show the Lambda support in Spring is the JdbcTemplate class. If we would like to obtain female employees and map them as an instance of type Employee, we could do something like this:

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

jdbcTemplate.query("SELECT first_name, last_name FROM employee WHERE gender = ?",
                   ps -> {ps.setString(1, "FEMALE");},
                   (rs) -> new Employee(rs.getString(1), rs.getString(2)));

The complete list of Spring 4.0 features can be found here.

Optional for injection points and MVC handler parameters in Spring 4.1

As of Spring 4.1, JDK 1.8’s java.util.Optional is now supported for @RequestParam, @RequestHeader, and @MatrixVariable controller method arguments. This means that while using Java’s Optional, you make sure that parameters are never null.

The following example shows an example of a @RequestParam in Spring MVC prior to version 4.1.

@RequestMapping(value="/iadvise")
public String findEmployee(@RequestParam(value = "employeeId") String employeeId) {
  StringBuilder response = new StringBuilder("id: ");
  response.append(employeeId.toUpperCase());
  return response.toString();
}

When calling the findEmployee method without providing an employeeId, the method will return a NullPointerException. This can be solved by Java’s Optional element.

@RequestMapping(value="/iadvise")
public String findEmployee(
  @RequestParam(value = "employeeId") Optional<String> employeeId){
  StringBuilder response = new StringBuilder("id: ");
  employeeId.ifPresent(value -> response.append(employeeId.toUpperCase()));
  return response.toString();
}

The same result can be achieved for the @RequestHeader, and @MatrixVariable annotations.

The complete list of Spring 4.1 features can be found here.

HTTP/2 server push

HTTP/2 general

In general HTTP/2 is about optimizing server resource usage. This is mainly achieved by using 1 connection between server and client and re-using that connection for all requests/responses for the duration of the session.

This is in sharp contrast with HTTP/1. Where a connection is created, a request is sent, a response is received and the connection is terminated. This is overhead is more or less hidden to the user because multiple connections are used in parallel.

HTTP/2 server push

HTML pages reference many other resources. Using HTTP/1 the client needs to parse the HTML page, identify the referenced resources and fetch them. Every round-trip incurring the connection setup/breakdown overhead.

Using HTTP/2 the server can send these referenced resources to the client before they are needed and because the same connection is used there is no connection setup/breakdown overhead.

Use cases

Pushing page resources before they are needed will make a site/application more responsive to it’s users. But doing this manually for all pages of an application is only going to be feasible for the smallest of applications.

Web/ UI component frameworks may push framework resources that are needed. Multiple approaches can be taken in this space. All framework resources can be pushed or only the resources that are needed based on the components of the framework that are used.

What is available

Since HTTP/2 is a draft spec, it is still early days for HTTP/2. Currently there is no standard Servlet API but that can’t stop us, Jetty already has an experimental API.

Google Chrome Canary has support for HTTP/2 when started with –enable-spdy4 as start parameter.

Firefox has support for HTTP/2 when the network.http.spdy.enabled.http2draft is switched on.

Test case

In order to test server push I’ve taken one of my panoramic vacation photos and sliced it up into 400 parts. This may be a little over the top but as with all tests we want to test the limits.

The test has been executed using 2 web-modules:

  • blog-http1-no-push – containing a servlet on URL /nopush that does not perform any pushes.
  • blog-http2-push – containing a servlet on URL /push that executes server pushes for the image slices.

The blog-http1-no-push web module was deployed to a Jetty server containing only the http, annotations and deploy modules running on port 8080.

The blog-http2-push web module was deployed to a Jetty server containing only the http2, annotations and deploy modules running on port 8443.

Both these setups are available as Docker images:

Both web modules contain a single servlet. The servlets take a rows & columns attribute as parameters. This allows us to control the amount of resources that are contained in the generated page. They also control the amount of resources that are pushed by the blog-http2-push web module.

During testing I did notice that the server sometimes becomes unstable when trying to push all 400 image slices. I’ve contacted the jetty users mailing list, perhaps some additional configuration needs to be set when pushing a lot of resources. I’m waiting for their reply.

How do you use HTTP/2 in code

Initially there was a push method on the Dispatcher class, but while writing this blog the Jetty project deprecated that method and made a PushBuilder available via the Request class.

final Request jettyRequest = (Request) getRequest();

jettyRequest
    .getPushBuilder()
    .push(resourcePath);

Checkout the sources on Github https://github.com/teyckmans/http2-push

Performance difference

In order to have a correct test case I’ve deployed the Docker images in the Google cloud in the us-central1-a zone in order to have real network overhead. Measurements have been taken with cache disabled in Google Chrome Canary using the load number.

HTTP/1 – no push
http://%5Bhost-external-ip%5D:8080/blog-http1-no-push/nopush?rows=5
3.01s (average of 6)

HTTP/2 – push
https://%5Bhost-external-ip%5D:8443/blog-http2-push/push?rows=5
1.51s (average of 6)

Pretty spectacular difference if you ask me.

Do It Yourself

I’ve uploaded the Docker images to the docker hub so you can try it out and experience the difference yourself.
Use the following command lines to run the test web-modules.

HTTP/1 – no push
docker pull teyckmans/blog-http1-no-push
docker run –name blog-http1-no-push-1a -i -t -p 8080:8080 teyckmans/blog-http1-no-push

HTTP/2 – push
docker pull teyckmans/blog-http2-push
docker run –name blog-http2-push-1a -i -t -p 8443:8443 teyckmans/blog-http2-push

5 hidden gems in Java 8

There’s been a lot of attention for the major new features of Java 8: Lambdas, the streaming API and the new Date and Time API. Of course these are the ones that make this a game changing release, but there’s more to Java 8. Inspired by José Paumard´s Devoxx talk 50 new things we can do with Java 8 I’d like to shed some light on 5 smaller features that will make your life as a Java developer easier. I won’t go 50 like José (and actually… neither did he), but these are the ones you definitely need to see.

Join me!

So we probably all had our fair share of recreating the same boilerplate code over and over again: iterating over a list of values in order to concatenate them with a delimiter to a single String. In Java 7 this would probably look something like this:

List<String> values = ...
StringBuilder result = new StringBuilder("[");
boolean first = true;
for(String item : values) {
  if(first) {
    first = false;
  } else {
    result.append(", ");
  }
  result.append(item);
}
result.append("]");
System.out.println(result.toString());

While this is certainly more concise and more readable than how the code would have looked in the 1.4 era, before generics and enhanced for-loops, but it still is a hideous pile of boilerplate for something very simple. So now for the Java 8 solution:

StringJoiner joiner = new StringJoiner(", ", "[", "]");
values.forEach(joiner::add);
System.out.println(joiner.toString());

This actually showcases not only the new StringJoiner, but two other Java 8 features as well: method references and the forEach() method on the Iterable interface.

While StringJoiner is actually meant for some behind-the-scenes processing for a Collector in the streaming API (http://blog.joda.org/2014/08/stringjoiner-in-java-se-8.html), it does eliminate a lot of boilerplate in more traditional code.

Longing for hashCode

When implementing your own hashCode() method for a class that has long fields, in the past you had to calculate the hash yourself or wrap the long value in a Long object and then call its hashCode() method. In order to avoid unnecessary creation of objects, Java 8 allows you to use the static method Long.hashCode(long value) for this.

Line it up!

Java 7 gave us the very convenient Files class with a lot of useful static helper methods for working files, amongst which Files.readAllLines(Path path). This class is also updated to make the best use of the Streaming API. So now we get the even more useful Files.lines(Path path), which does not return a List of all the lines, but a Stream. This is probably a better programming model in almost all cases. When you read all the lines in a file, you will probably want to process them somehow instead of keeping them in memory. Below an example of reading all the lines in a file and printing out only those lines that start with an “A”.

Path file = Paths.get("path", "to", "file.txt");
try (Stream<String> lines = Files.lines(file)) {
  lines
    .filter(s -> s.startsWith("A"))
    .forEach(System.out::println);
} catch (IOException ioe) {
  // ...
}

Repeat after me

A new feature that will probably find most of its use in the Java EE world, is @Repeatable. By annotating your annotation type with the meta-annotation @Repeatable, it can be placed at the same element more than once. Under the hood this still wraps the separate annotations in a container annotation, but it reads a lot better.

Since the annotation is not used within Java SE 8 itself, there are only a lot of imaginary examples circulating on the internet. But then again this feature was introduced with Java EE in mind. So below snippet (derived from the Java EE 7 spec) will likely be a valid JAX-B example in Java EE 8:

public class Foo {
  @XmlElement(name="A", type=Integer.class)
  @XmlElement(name="B", type=Float.class)
  public List items;
}

Which will below the surface be translated to the current notation:

public class Foo {
  @XmlElements(
    @XmlElement(name="A", type=Integer.class),
    @XmlElement(name="B", type=Float.class)
  )
  public List items;
}

By default

Default methods on interfaces are often presented as a by-product of Lambda’s, but they can make it a lot easier to create a sustainable future-proof API. A default method is a method on an interface of which the (default) implementation is already provided.

Say for instance your public API exposes the following interface:

public interface Foo {
  void addListener(FooListener listener);
}

Say for instance that you want to add the possibility to add multiple listeners in one go without breaking the implementations of your customers. This can be achieved by adding a default method:

public interface Foo {
  void addListener(FooListener listener);

  default void addListeners(Collection<FooListener> listeners) {
    listeners.forEach(this::addListener);
  }
}

And many more

While I stick to five here, there are many, many more additions to Java 8. You can find the full list here: http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html.

New in Java 8 : Consumers and Predicates : a simple introduction

The java.util.function package is new in Java 8 and contains interfaces that are used for lambda expressions and functional references. In this blog, I give a brief introduction of  2 interfaces of this package :

  • Consumer
  • Predicate

For the examples in this blog, we have a list of invoices with name, amount and category :

public class Invoice {
   private String name,amount,category;
   public Invoice(String name,String amount,String category) {
     super;
     this.name=name;
     this.amount=amount;
     this.category=category;
   }
   public String getName() {
     return this.name;
   }
   public String getAmount() {
     return this.amount;
   }
   public String getCategory() {
     return this.category;
   }
}

To generate a list of invoices, we’ll use the following method:

public static List<Invoice> generateInvoices()  {
   List<Invoice> list = new ArrayList<Invoice>();
   list.add(new Invoice("Oracle","1000","SOFTWARE"));
   list.add(new Invoice("Microsof","30000","HARDWARE"));
   list.add(new Invoice("Apple","5000","SOFTWARE"));
}

Consumer

A Consumer is an interface that ‘consumes’ an object. It takes an argument and does something with it. It does not return a result.

The Consumer interface has 2 methods :

  • void accept(T t) : contains the code that is executed on t
  • default Consumer<T> andThen(Consumer<? super T> after) : This method returns a consumer that is executed after the previous one and enables you to execute a chain of consumers.

For this demo, we are using the (new in Java8) method of the Collection API :

Collection.forEach(Consumer<? super T> action)

This method executes the consumer ‘action’ on every item of the collection.

First we create 2 methods that each return a Consumer object. The first will print the name of the invoice, the second prints the amount.

Finally we use these 2 methods in a Collection.foreach method.


public static Consumer<Invoice> printName() {
    return new Consumer<Invoice>() {
         public void accept(Invoice invoice) {
           System.out.println(invoice.getName());
         }
    };
}

public static Consumer<Invoice> printAmount() {
    return new Consumer<Invoice>() {
         public void accept(Invoice invoice) {
           System.out.println(invoice.getAmount());
         }
    };
}

generateInvoices().forEach(printName().andThen(printAmount());

As you can see in the last line, first the printName() is executed, and then the printAmount(). This line will print the following :
Oracle
1000
Microsoft
3000
Apple
5000

When an error occurs in the foreach method, an exception is thrown, and further processing of the List stops.

Predicate

A Predicate is an interface that is used to assign lambda expressions. It has a functional method :

boolean Test(T t )

Predicates are used as stream operations. Stream operations can be executed on Collections in order to execute complex data processing queries. But in this blog we’ll keep it simple, we just want to select all the invoices with category=’HARDWARE’, and put them in a new List.

Using a predicate in combination with the new Streams API, will simplify and shorten our code and make it more readable.

First we define our predicate, and then we’ll use it on our List of invoices. The stream method will filter the List using our predicate, and then collect the items that fulfill the predicate in a new List.

public static Predicate<Invoice> isHardware() {
     return i -> i.getCategory().equals("HARDWARE");
}

List<Invoice> listHardware = generateInvoices().stream.filter(isHardware()).collect(Collectors.<Invoice>toList());

Our new list will now contain 1 invoice, the one from Microsoft which has ‘HARDWARE’ as category.
As you can see, Predicate is a class that contains a function that we can pass to other classes. Actually it is just a reference to a function, AKA ‘a function reference’.
With Streams, you also sort and map data, before collecting, but that’s for another blog.

So that’s it for now. I hope this blog has shown that, by using Consumers and Predicates, our code will become shorter, cleaner and more readable.

 

Introduction to Websockets and JSON-P API in JEE7

Websockets (JSR 356) and the JSON-Processing API (JSR 353) are both introduced in the JEE7 specification. Together with JavaScript an HTML5, they enable web applications to deliver a richer user experience.

Websockets allow you to communicate bidirectional and full duplex over TCP, between your server and different kind of clients (browser’s, JavaFX… ). It’s basically a push technology, where, for example events or data originating from the server or a client, can be pushed to all the other connected clients.

In our demo , JSON strings are send between client and server, so that’s where the JSON Processing API comes in. It’s a  portable API that allows you to parse, generate, transform and query JSON by using the streaming or model API. But you could also send XML or any other proprietary format.

Serverside components

  1. A java class annotated with
    @ServerEndpoint(value=”/endpoint”, decoders=EncodeDecode.class, encoders=EncodeDecode.class)
    with following method annotations :
    @OnOpen : when connections is open
    @OnMessage : when a message comes in
    @OnClose : when a message is closed
  2. A java class that encode/decodes the message from/to JSON and Java object. (That’s where the JSON-P API comes in).

Clientside component

An html file that contains JavaScript to communicate with our server endpoint. Communication is done through a WebSocket object, declared as follows :

connection = new WebSocket(‘ws://localhost:8080/mywebsocket/endpoint’);

will trigger the @OnOpen method of our server side endpoint.

connection.onmessage : fired when a message comes in

connection.send : will trigger the OnMessage annotated method of our endpoint

connection.close : will trigger the OnClose annotated method of out endpoint

Demo

It’s a screen that sends messages to all the connected clients, including itself. When the client opens a connection on the server, his session is added to a list of active sessions. When a client sends a message to the server, it is distributed to all the sessions in the list. When the client closes his browser tab or window, his session is removed from the list. The data that we send, can be any complex JSON or XML model. To keep it simple, we just send a simple string.

This application needs to be deployed on a JEE7 compliant servet. So at this moment (May 2014) it will only run on Glassfish 4.0 or WildFly 8.

The war file can be found here. After deployment, open url (for Glassfish) http://localhost:8080/mywebsocket/socket.html.

 The Code

Java endpoint

package be.iadvise.mywebsocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value="/endpoint", decoders=EncodeDecode.class, encoders=EncodeDecode.class)
public class MyEndPoint {
 // contains list of active sessions
 private static List<Session> sessions = Collections.synchronizedList(new ArrayList<Session>());

 @OnOpen
 public void onOpen (Session s) {
 sessions.add(s);
 System.out.println("Open session : no of sessions = "+sessions.size());
 }

 @OnMessage
 public void onMessage (MyMessage msg, Session s) throws IOException, EncodeException {
 for (Session session : sessions) { // loop over active sessions and send the message.
 session.getBasicRemote().sendObject(msg);
 }
 }
 @OnClose
 public void onClose (Session s) {
 sessions.remove(s); // remove session from the active session list.
 }
}

Java Decode/Encode message

package be.iadvise.mywebsocket;

import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.stream.JsonGenerator;
import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;

/**
 * This class will encode/decode the messages from/to the client.
 * Decoder : from client to server -> converts the JSON to MyMessage object
 * Encoder : from server to client -> converts MyMessage object to JSON
 *
 * We are using JSON, but you can use XML or any other format.
 */
public class EncodeDecode implements Decoder.Text<MyMessage>, Encoder.Text<MyMessage> { 

 @Override
 public MyMessage decode(String txt) throws DecodeException {
 Reader reader = new StringReader(txt);
 JsonReader jsonReader = Json.createReader(reader);
 JsonObject object = jsonReader.readObject();
 String text = object.getJsonString("text").getString();
 return new MyMessage (text);
 }

 //Check if decode is possible. If not, return false
 @Override
 public boolean willDecode(String s) {
 System.out.println("Will decode asked for " + s);
 return true;
 }

 @Override
 public void init(EndpointConfig config) {
 System.out.println("init called on chatdecoder");
 }

 @Override
 public void destroy() {
 System.out.println("destroy called on chatdecoder");
 }

 @Override
 public String encode(MyMessage object) {
 System.out.println("I have to encode " + object);
 StringWriter sw = new StringWriter();
 JsonGenerator generator = Json.createGenerator(sw);
 generator.writeStartObject();
 generator.write("text", ((MyMessage)object).getText());
 generator.writeEnd();
 generator.flush();
 String answer = sw.toString();
 System.out.println("I encoded an object: " + answer);
 return answer;
 }
}

Java message


package be.iadvise.mywebsocket;

public class MyMessage {
private String text;
public MyMessage(String text) {
super();
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "MyMessage [text=" + text + "]";
}
}

The html file


<html>
<head>
<script language="javascript">
var connection;
var me;
function openSocket() {
connection = new WebSocket('ws://localhost:8080/mywebsocket/endpoint');
connection.onmessage = function(evt) {
var x = JSON.parse(evt.data);
mytext = x.text;
var chld = document.createElement("p");
chld.innerHTML = mytext;
var messages = document.getElementById("messages");
messages.appendChild(chld);
}
}

function talk() {
var txt = document.getElementById("msg").value;
var message = {
'text':txt
};
connection.send(JSON.stringify(message));
}
function closeSocket() {
alert('closing socket')
connection.onclose = function () {}; // disable onclose handler first
connection.close();
}
</script>

<script type="text/javascript">
if (window.addEventListener) { // all browsers except IE before version 9
window.addEventListener ("beforeunload", closeSocket, false);
}
else {
if (window.attachEvent) { // IE before version 9
window.attachEvent ("onbeforeunload", closeSocket);
}
}
</script>
</head>
<body onLoad="openSocket();">
<p>
SimpleWebSocket
</p>
<!-- <table id="chatbox" style="display:none"> -->
<table id="chatbox">
<tr><th width="400">messages</th></tr>
<tr>
<td width="400" id="messages">
</td>
</tr>
<tr>
<td>
<input type="text" id="msg"/>
<input type="submit" value="send" onclick="talk(); return false;"></input>
</td>
</tr>
</table>
</body>
</html>

 Conclusion

Websockets are a huge improvement for building rich applications. This is the first time that push technology is actually build in the JEE framework. Before that, we had to use polling or other techniques in order to get the same results. In this blog, I showed that you don’t need much code to start off. Once you get this working, you can gradually go further building more complex sockets.