Tuesday 28 October 2014

Run your Maven applications with TomEE plugin

If you are coding JEE applications you will probably need a server which allows you to quickly run and test your code.  If you are looking for a painless solution then TomEE might be your favorite choice. In particular if you are working with Maven projects.

At the moment the current version of TomEE is 1.7 which is based on Tomcat 7 and supports JEE6. The only thing you have to do is to include and configure the tomee-maven-plugin in your pom.xml:

<plugin>
   <groupId>org.apache.openejb.maven</groupId>
   <artifactId>tomee-maven-plugin</artifactId>
   <version>1.7.1</version>
   <configuration>
      <tomeeVersion>1.7.1</tomeeVersion>
      <tomeeClassifier>plus</tomeeClassifier>
      <synchronization>
         <extensions>
            <extension>.class</extension>
         </extensions>
      </synchronization>
      <reloadOnUpdate>true</reloadOnUpdate>
   </configuration>
</plugin>

Depending on the features you need TomEE supports different profiles. To start a TomEE server and run your application simply type

mvn clean install tomee:run

The synchronization block in the configuration is optional and allows you to redeploy your application automatically after each mvn clean install of your application.

Thursday 28 August 2014

Get images from a webcam and do some face recognition

Today I show you a simple way to get images of your webcam and do some fancy face recognition. To glue it together I use a small JavaFX application and display the video stream as well as the recognized faces. You can download or checkout the complete project from: https://github.com/tobiasdenzler/face-recognition.

Before we start you should have a quick look at the webcam-capture library we will use. It is a really cool project and offers lot more features than we are investigating now. If you are interested in image capture/recognition stuff you might also like to dive into OpenIMAJ, a quite extensive set of image analysis tools. The webcam-capture library partly depends on this toolset.

The webcam-capture library is available on maven-central. The classes from OpenIMAJ which we will need to recognize some faces you can get from http://maven.openimaj.org repository. Check the pom.xml for details.

<dependency>
    <groupId>com.github.sarxos</groupId>
    <artifactId>webcam-capture</artifactId>
    <version>0.3.9</version>
<dependency>
    <groupId>org.openimaj</groupId>
    <artifactId>faces</artifactId>
    <version>1.1</version>
</dependency>

It is quite easy to access the stream from your webcam and get an image from there. First, get your default camera, then set your view size and open the webcam. You will find some great examples on how to use the webcam-capture library on their Github site here. To get an image from the webcam you simply call getImage().

Webcam webcam = Webcam.getDefault();
webcam.setViewSize(new Dimension(640, 480));
webcam.open();

BufferedImage capture = webcam.getImage();

For face detection tasks you can use different detectors from the openimaj package. Here we use a very basic one which returns a list of the recognized face patches.

HaarCascadeDetector detector = new HaarCascadeDetector();
Lisz<DetectedFace> faces = detector.detectFaces(ImageUtilities.createFImage(capture));

That's all the magic. To use it inside a JavaFX application you start a new thread in which you read your webcam stream and do the recognition tasks. See my sample project on Github for more details.

Tuesday 22 July 2014

JavaFX: Pie chart using dynamic data

The JavaFX SDK contains some pretty nice charts which you can use without much configuration. The documentation from JavaFX provides tutorials for each of the 6 chart types plus a section about styling the charts using CSS.

In the following examples we use a PieChart and feed it with dynamically changing data. We will count each distinct character of an input text field and display the new values while the user changes the input value.

package sample;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class PieChartExample extends Application {

    // list that holds the values you want to display on the chart
    private static ObservableList<PieChart.Data> list = FXCollections.observableList(new ArrayList<PieChart.Data>());

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox root = new VBox();
        Scene scene = new Scene(root, 1024, 768);

        // text field for user input
        final TextField textField1 = new TextField();
        textField1.setPrefWidth(1000);

        // listener will be invoked whenever the user changes the value
        textField1.textProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                list.clear();
                
                // fill the list containing data for the chart with the values from the map
                for(Map.Entry<String, Integer> entry : countCharactersOfString(newValue).entrySet()) {
                    list.add(new PieChart.Data(entry.getKey(), entry.getValue()));
                }
            }
        });

        // set up the pie chart
        PieChart pieChart = new PieChart();
        pieChart.setData(list);
        pieChart.setLegendVisible(false);
        pieChart.setPrefHeight(900);

        root.getChildren().addAll(textField1, pieChart);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * Count all distinct characters of a string an put them in a map.
     * 
     * @param input String from user input
     * @return map with character as key and occurrence as value
     */
    private Map<String, Integer> countCharactersOfString(String input) {

        Map<String, Integer> countMap = new HashMap<String, Integer>();
        char[] charArray = input.toCharArray();

        for (char currentChar : charArray) {
            String current = String.valueOf(currentChar);
            if (countMap.containsKey(current)) {
                countMap.replace(current, countMap.get(current) + 1);
            } else {
                countMap.put(current, 1);
            }
        }

        return countMap;
    }
}

If you enter some characters in the textfield at the top you will see that the pie chart dynamically changes its values. We listen to changes in the input text field and count the entered characters and the ObservableList reflects every manipulation we do in the list also to the chart.





Wednesday 5 February 2014

Twitter4J: Read public sample stream from Twitter

Today I am going to show you how to use Twitter4J to read a public sample stream of tweets from Twitter. Twitter4J is an unofficial Java library for the Twitter API and you can use it easily to integrate Twitter services in your application. Besides reading streams you can do a lot more like post or search Tweets. Twitter itself provides a bunch of documentation for developers and also a chapter on their Streaming API. This API gives you low latency access to Twitter's global stream of Tweet data.

You can get twitter4j-core from Maven central repository. For the streaming functionality you also need the twitter4j-stream library:

<dependency>
   <groupid>org.twitter4j</groupid>
   <artifactid>twitter4j-core</artifactid>
   <version>[3.0,)</version>
<dependency>
<dependency>
    <groupid>org.twitter4j</groupid>
    <artifactid>twitter4j-stream</artifactid>    
    <version>[3.0,)</version>
</dependency> 

Access to Twitters Streaming API is done by OAuth and you have to register your application first to get the needed set of credentials. After signing in with your regular Twitter account you can generate the following credentials and write it down in a twitter4j.properties file.

oauth.consumerKey=************
oauth.consumerSecret=************
oauth.accessToken=************
oauth.accessTokenSecret=************

To read the stream you can get a TwitterStream from the TwitterStreamFactory. Then you implement a Listener called StatusListener with a bunch of methods and your almost done. In the end you start streaming by calling the sample() method (that will stream from the Twitter sample stream).

import twitter4j.*;

public class TwitterStreamingClient {

   public static void main(String[] args) {

      TwitterStream stream = new TwitterStreamFactory().getInstance();
      stream.addListener(new StatusListener() {

         @Override
         public void onStatus(Status status) {
             System.out.println(status.getText());
         }

         @Override
         public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {}

         @Override
         public void onTrackLimitationNotice(int i) {}

         @Override
         public void onScrubGeo(long l, long l2) {}

         @Override
         public void onStallWarning(StallWarning stallWarning) {}

         @Override
         public void onException(Exception e) {}
      });
      stream.sample();
   }
}

The Status object gives you all information about a Tweet like content, user, geolocation and many others. Check the Twitter4J documentation for more details.

See also

Sunday 29 December 2013

How to use @Asynchronous in JEE

Since Java Enterprise Edition (JEE) 6 and EJB 3.1 (JSR 318) we can use the @Asynchronous annotation to call a method asynchronously.

The following example contains a Stateless Session Bean with three asynchronous methods, each one of them running for a different amount of time (1, 3 and 5 seconds) and returning a simple String value.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import java.util.concurrent.Future;

@Stateless
public class AsynchronousBean {

    private static final Logger LOG = LoggerFactory.getLogger(AsynchronousBean.class);

    @Asynchronous
    public Future<String> workFor5Seconds() throws Exception {
        LOG.info("==> workFor5Seconds");
        Thread.sleep(5000);
        LOG.info("<== workFor5Seconds");
        return new AsyncResult<String>("test1");
    }

    @Asynchronous
    public Future<String> workFor3Seconds() throws Exception {
        LOG.info("==> workFor3Seconds");
        Thread.sleep(3000);
        LOG.info("<== workFor3Seconds");
        return new AsyncResult<String>("test2");
    }

    @Asynchronous
    public Future<String> workFor1Second() throws Exception {
        LOG.info("==> workFor1Second");
        Thread.sleep(1000);
        LOG.info("<== workFor1Second");
        return new AsyncResult<String>("test3");
    }
}

We can test the AsynchronousBean with a small unit test using an EJBContainer to set up the environment. We call all three asynchronous methods in a row and use the Future type for the return result.

import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class AsynchronousTest {

    private static final Logger LOG = LoggerFactory.getLogger(AsynchronousTest.class);

    public static EJBContainer container;

    AsynchronousBean asynchronousBean;

    @Before
    public void setUp() throws Exception {
        container = EJBContainer.createEJBContainer();
        container.getContext().bind("inject", this); 
        asynchronousBean = (AsynchronousBean) container.getContext().lookup("java:global/[module-name]/" + AsynchronousBean.class.getSimpleName());
    }

    @Test
    public void asynchronousTest() throws Exception {

        final Future<String> future1 = asynchronousBean.workFor5Seconds();
        final Future<String> future2 = asynchronousBean.workFor3Seconds();
        final Future<String> future3 = asynchronousBean.workFor1Second();

        LOG.info("Do something else..");
        Thread.sleep(1000);

        final String result1 = future1.get();
        final String result2 = future2.get();
        final String result3 = future3.get();

        LOG.info("Result from workFor5Seconds is: {}", result1);
        LOG.info("Result from workFor3Seconds is: {}", result2);
        LOG.info("Result from workFor1Second is: {}", result3);
    }

    @AfterClass
    public static void destroy() throws Exception {
        if(container != null) {
            container.close();
        }
    }
}

If we analyze the output of the logging we see characteristics of @Asynchronous. In a sequential processing we would be stuck in the first method waiting for 5 seconds to return and then call the next one. Using asynchronous calls we can enter all methods concurrently and get the final result if it is ready.

[INFO ] Do something else..
[INFO ] ==> workFor5Second
[INFO ] ==> workFor3Seconds
[INFO ] ==> workFor1Seconds
[INFO ] <== workFor1Second
[INFO ] <== workFor3Seconds
[INFO ] <== workFor5Seconds
[INFO ] Result from workFor5Seconds is: test1
[INFO ] Result from workFor3Seconds is: test2
[INFO ] Result from workFor1Second is: test3

See also

Tuesday 22 October 2013

Hibernate Caching with Hazelcast

Probably you already know Hazelcast, the open source clustering and highly scalable platform for Java. If you do not know Hazelcast then visit their website and watch the nice intro video to get an idea of it.

As in-memory data-grid Hazelcast is well suited for a distributed cache. In this post I will show you how to setup Hazelcast as a second level cache for Hibernate.  For further information you can check the documentation or download my sample project from Github.

The important dependencies for the Hazelcast part are hazelcast and hazelcast-hibernate4. As the current Hazelcast version does not support Hibernate 4 you need an additional implementation for that.

<dependency>
    <groupid>com.hazelcast</groupid>
    <artifactid>hazelcast</artifactid>
    <version>3.0.2</version>
</dependency>
<dependency>
    <groupid>com.hazelcast</groupid>
    <artifactid>hazelcast-hibernate4</artifactid>
    <version>3.0.2</version>
</dependency>

In your persistence.xml you add the following lines to activate the second level cache and configure Hibernate to use Hazelcast for it.

<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_minimal_puts" value="true" />
<property name="hibernate.cache.hazelcast.use_lite_member" value="true" />
<property name="hibernate.cache.region.factory_class" value="com.hazelcast.hibernate.HazelcastCacheRegionFactory" />

In Hibernate 4 you now can annotate your entity with

@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)

to enable caching for that particular class. There are some configuration you can do using the hazelcast.xml. Check the sample project to see the complete setup with some tests to run.

See also:


Friday 20 September 2013

JAX-RS 2.0 using JSON and Persistence with JEE7

This post is about building a basic RESTful application with Maven using the JAX-RS 2.0 API (JSR339: JAX-RS 2.0). The data is exchanged using the JSON format. You will also see how JEE7 can simplify persistence for you. As server we will use Glassfish4 which contains the reference implementation of JEE7. At the end we will test our service with curl and with a unit test.

You can checkout this project from Github or download the archive here.

POM

So let's start. The only dependency we need in our pom.xml is the following:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

Persistence

To be able to persist the data we first create a basic entity class, nothing special about that.

@Entity
public class Customer {

    @Id
    private long id;
    private String name;
    
    // getters, setters and others
    ...
}

Using JEE7 we now have the possibility of using a default datasource for persistence. The persistence.xml file looks a bit shorter though.

<persistence-unit name="mypu" transaction-type="JTA">
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create">
    </property></properties>
</persistence-unit>

That's all about your persistence configuration. Featured by JEE7 we will use a default datasource under java:comp/DefaultDataSource. This is defined in Glassfish4 and connects to an integrated Derby database instance.

CRUD

To work with the Customer object we first need a service that handles the persistence. The following stateless bean offers the common CRUD functionality.

@Stateless
public class CustomerService {

    @PersistenceContext
    EntityManager em;

    public void create(Customer entity) {
        em.persist(entity);
    }

    public void update(Customer entity) {
        em.merge(entity);
    }

    public void remove(long id) {
        Customer customer = find(id);
        em.remove(customer);
    }

    public Customer find(long id) {
        return em.find(Customer.class, id);
    }
}

To make sure that Glassfish find our bean we also need the beans.xml in the WEB-INF directory.

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
bean-discovery-mode="all"></beans>

Make sure you use the bean-discovery-mode attribute because otherwise the container will not find your bean. At this point we are done with persistence so far.

RESTful

So let's step further to the RESTful part of our project. What we need is another stateless session bean with a method for each CRUD operation we want to support. The only thing we have to do for getting RESTful functionality is to use some annotations. On class level we annotate @Path("customers") as path to our service. Then we use @POST, @GET, @PUT and @DELETE to denote the different RESTful operations. As we want to communicate through JSON we use the MediaType.APPLICATION_JSON.

@Stateless
@Path("customers")
public class CustomerResource {

    @Inject
    CustomerService service;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void create(Customer customer) {
        service.create(customer);
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Customer find(@PathParam("id") long id) {
        return service.find(id);
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public void update(Customer customer) {
        service.update(customer);
    }

    @DELETE
    @Path("{id}")
    public void delete(@PathParam("id") long id) {
        service.remove(id);
    }
}

There is one last thing we need to do to complete our REST configuration. @ApplicationPath("api") defines the global path to our application and this class has to extend javax.ws.rs.core.Application.

@ApplicationPath("api")
public class RESTConfig extends Application {
}

That's all the magic. Start the integrated Derby database with asadmin start-database and fire up your Glassfish server to try your new RESTful service.

curl

You can do a quick functionality check using curl. To send a POST request to your server and thereby create and persist the data do something like this:

curl -i -X POST -d '{"id":1,"name":"Annabelle"}' http://localhost:8080/jee7-rest-crud/api/customers -H 'Content-Type: application/json'

Basically that means, send a POST request containing that string to this address using the JSON format. Doing it right, your server will return something like that:

HTTP/1.1 204 No Content
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition  4.0  Java/Oracle Corporation/1.7)
Server: GlassFish Server Open Source Edition  4.0
Date: Fri, 20 Sep 2013 05:11:11 GMT

Status code 204 No Content is perfect here because we defined our RESTful service not to send any data back on a POST request. If you want to read the data you saved before you can send a GET request:

curl -i -X GET http://localhost:8080/jee7-rest-crud/api/customers/1 -H 'Content-Type: application/json'

Your server should return a result like this:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition  4.0  Java/Oracle Corporation/1.7)
Server: GlassFish Server Open Source Edition  4.0
Content-Type: application/json
Date: Fri, 20 Sep 2013 05:10:16 GMT
Content-Length: 27

{"id":1,"name":"Annabelle"}

The PUT (update) and DELETE (remove) operations can be tested in the same way.

Unit Test

If you want to unit test your RESTful service you can now use the new ClientBuilder from the JAX-RS 2.0 API coming with JEE7. But you will need some extra dependencies for the JSON data binding because Java do not yet provide that (likely to come with Java 8).

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.6.3</version>
    <scope>test</scope>
</dependency>

To do the data binding for JSON we need to implement the MessageBodyReader<T> and MessageBodyWriter<T> from the javax.ws.rs.ext package. These classes need to be annotated with @Provider and @Consumes respectively @Produces. Check the CustomerMessageBodyReader and CustomerMessageBodyWriter classes of the project for implementation details.

Now we can write a unit test to check the CRUD functionality of our RESTful service.

public class CustomerClientTest {

    private static final String SERVER = "http://localhost:8080/jee7-rest-crud/api/customers";

    private WebTarget target;

    @Before
    public void setUp() {
        Client client = ClientBuilder.newClient();
        client.register(CustomerMessageBodyReader.class);
        client.register(CustomerMessageBodyWriter.class);
        this.target = client.target(SERVER);
    }

    @Test
    public void crud() {

        Customer origin = new Customer(1, "Mathilda");
        Entity entity = Entity.entity(origin, MediaType.APPLICATION_JSON);

        // create
        Response response = target.request(MediaType.APPLICATION_JSON).post(entity, Response.class);
        assertThat(response.getStatus(), equalTo(204));

        // read
        Customer result = target.path(String.valueOf(origin.getId())).request(MediaType.APPLICATION_JSON).get(Customer.class);
        assertThat(result, equalTo(origin));

        // update
        entity.getEntity().setName("Annabelle");
        target.request().put(entity);

        // delete
        target.path(String.valueOf(origin.getId())).request(MediaType.APPLICATION_JSON).delete();
    }
}

First we build the client and register the custom reader and writer classes. Then we set the target to the address of our service. The rest is straight forward testing of the various functionality we have built.

See also