Java 8 Lambda : the very basics

Functional interface

In many cases – when talking about Java 8 – lambda-functions are the first thing that comes up. I found it a concept hard to grasp, as it slightly changes the way you think about coding. In this blog, I would like to show you some very simple examples, and explain what is what in the lambda world.

In versions prior to Java 8, we had SAM interfaces : Single Abstract Method-interfaces. In Java 8, the concept of SAM-interfaces has been re-created and called “functional interfaces”. These interfaces can be used in lambda-expressions. Here’s a definition of such an interface that we will be using in the examples.

@FunctionalInterface
interface MyCalculator {
	public double calculate(double val1, double val2);
}

The “FunctionalInterface” annotation is used to generate compiler level errors, when the interface is not a functional interface. A functional interface is an interface with 1 abstract method. The annotation is not required, but improves the readability of your code.

Using the lambda

When the functional interface is created, you can declare a variable to be assigned with a lambda-expression.

MyCalculator multiply = (value1, value2) -> value1 * value2;
MyCalculator sum = (value1, value2) -> value1 + value2;
System.out.println(“multiply = “+multiply.calculate(5,6));
System.out.println(“sum = “+sum.calculate(5,6));

Generates following output:
multiply = 30.0
sum = 11.0

So if you are wondering what is what in a lambda-expression :
Before the arrow = variables of your function
After the arrow = code to be executed by the abstract method of the functional interface

If we would do this the ‘old-school’ way, our code would look like this :

MyCalculator multiply = new MyCalculator() {
	public double calculate(double val1, double val2) {
					return val1 * val2;
				}
			};
MyCalculator sum = new MyCalculator() {
	public double calculate(double val1, double val2) {
					return val1 + val2;
				}
			};
System.out.println("multiply = "+multiply.calculate(5,6));
System.out.println("sum = "+sum.calculate(5,6));

The advantage of lambda is pretty clear : less code, better readability.

If you want to define more than 1 line of code, write it like this :

MyCalculator calc = (value1, value2) -> {
			System.out.println("Before calculating");
			double result = value1* value2* 3;
			System.out.println("After calculating");
			return result;
};
System.out.println(calc.calculate(3, 4));

Generates the following output:
Before calculating
After calculating
36.0

Use of non-local variables in lambda expressions

In versions prior to Java 8, the following code :

Calendar cal = Calendar.getInstance();
MyCalculator sum = new MyCalculator() {
	public double calculate(double val1, double val2) {
		cal.setFirstDayOfWeek(Calendar.SUNDAY);
		return val1 + val2;
	}
};

would generate an error :
“Cannot refer to the non-final local variable cal defined in an enclosing Scope”
on statement
cal.setFirstDayOfWeek(Calendar.SUNDAY);

because the variable “cal” was not defined as final.

The Java 8 compiler has a new capability that will convert non-local variables, used in lambda-expressions and anonymous inner class methods, automatically to final.
So in Java 8, this code will actually compile. Even better: now, we can write the previous code as a lambda-expression :

Calendar cal = Calendar.getInstance();
MyCalculator sum2 = (value1,value2) -> {
cal.setFirstDayOfWeek(Calendar.SUNDAY);
			return value1+value2;
		};

Streams API and lambdas

New in Java 8 is the Stream API (java.util.stream). According to Oracle’s documentation : “A stream is not a data structure that stores elements; instead, it transports elements from a source (data structure, array, generator function, or an I/O channel), through a pipeline of computational operations.”

This is where the lambdas make their entrance, as a pipeline is a sequence of lambda expressions that can process or interrogate every element in the stream. In short : by using streams and lambda’s, we can execute a whole bunch of operations on a Collection, all in 1 statement.

Suppose we want to print out every even number from a list of Integers.

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<Integer> evenList = list.stream().filter(value -> value%2==0).collect(Collectors.toList());
evenList.stream().forEach(value -> System.out.println(value));

In the second line, the filter method will return the values matching the predicate, in this case, a lambda-expression. The collect method will return the result list.
On the third line, we use a stream to print out every value of our new list, containing the even values.

If you had to write the above code in Java 7, you would need more code, so more possible flaws, less readability.
But there is more :

Map<Person.Sex, List<Person>> byGender = roster.stream().collect(Collectors.groupingBy(Person::getGender));

In 1 line of code, from a list of person objects, we create a map with the gender as the key.

Read the Java Doc on java.util.streams, and you’ll discover a whole new way of writing code, including parallel processing of your stream. Also, check out the Collectors API where you can find methods to convert your collections into other sorts of collections, without any for loops, etc…

The better you understand lambdas and streams, the more you’ll understand why they are such a hot issue in the Java world, the more you’ll improve your code!

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…

 

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.

 

New in Java 8 : Default and static methods in interfaces

Default method’s  (aka Defender methods) in interfaces are new in Java 8. They enable you to define a default implementation of a method in the interface itself.

If an interface is implemented by several classes, it’s hard to add method’s afterwards, as it will break the code and require all implementing classes to define the method as well. Adding a method to the interface, and defining a default implementation for it, will resolve this problem.

Here’s a code example :


public Interface Draw {

public void drawCircle();

   default public void drawRectangle() {

      System.out.println("draw a rectangle");

   }

}

Implementing classes that have not defined the drawRectangle() method, will print “draw a rectangle” when drawRectangle() is executed on them.

Interfaces that extend this interface can

  • define nothing, in which case the method will be inherited
  • declare the default method again with no implementation, which will make it abstract
  • Redefine the default method so it get’s overridden

These default methods were added to Java in order to be able to implement the new Streams API. As they needed to update the Collection interface, adding the stream() and parallelStream() methods. If they didn’t had the default method, they should have updated all classes that implement the Collection interface.

Static methods

Also new in Java 8 is the use of static method’s in an Interface.

So now, drawRectangle()  could also be defined as a static method, but that would give the impression that it is a utility or helper method, and not part of the essential core interface. So in that case, it’s better to go for the default method.

You could argument that an abstract class would have done the job as well. But as Java has single inheritance, that choice would narrow down our the design possibilities. And as the poster above your bed is shouting every day : ‘Favor composition over inheritance!!’ right ? So we want to avoid inheritance anyway.

So what will happen if you try to implement 2 interfaces with the same default methods ? Well, you will get the following compile time error :

Duplicate default methods named [methodname] with the parameters () and () are inherited from the types [interface1] and [interface2]

To avoid this error, choose an implementation of one of the interfaces :

interface Draw{
   default void circle() {
     System.out.println("draw circle");
   }
}
interface Print{
   default void circle() {
     System.out.println("print circle");
   }
}

class MyClass implements Draw, Print {
   @Override
   public void circle() {
     Draw.super.circle();
   }
}

That’s it, a quick overview of this new feature in Java 8.

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.

 

wpg_docload.download_file : mime type not recognized by client

For a project we are currently working on, we needed to generate, and send a Word 2010 document to the client. The document was generated by a great PL/SQL document generation tool called Doxxy, and was sent to the client using the wpg_docload package. This is a standard Oracle pl/sql package that can be used to download files, BLOBs and BFILEs.

Before the download, we set the Content-type in the http header as follows :

owa_util.mime_header('application/vnd.openxmlformats-officedocument.wordprocessingml.document',FALSE);

When sending the document to the client, we got the following popup in our browser :

Image

So it looked like our browser didn’t recognized that this was an Word 2010 document.

Looking at the response header, using Firebug, we got the following result :

Image

Somehow the content type for Word 2010 was overwritten to text/html; charset=utf-8.

So, time for the good old trial and error approach, which, after a while, paid off.

Before setting the response header to : owa_util.mime_header(‘….’,FALSE); we need to issue the following commands :

htp.flush();
htp.init();

Now the code looks like this  :

-- first clear the header
 htp.flush;
 htp.init;
 -- set up HTTP header
 owa_util.mime_header('application/vnd.openxmlformats-officedocument.wordprocessingml.document', FALSE);
 -- set the size so the browser knows how much to download
 htp.p('Content-length: ' || DBMS_LOB.getlength(v_blob));
 -- the filename will be used by the browser if the users does a save as
 htp.p('Content-Disposition:attachment; filename="'||nvl(v_filename,'export')||v_ext||'"');
 -- Set COOKIE (for javascript download plugin)
 htp.p('Set-Cookie: fileDownload=true; path=/');
 -- close the headers
 owa_util.http_header_close;
 -- download the BLOB
 wpg_docload.download_file(v_blob);

After adding these 2 lines, we got the correct mime type :

Image

Many thanks to Willem Albert and Bjorn Fraeys for delivering the content for this blog !