Using JAX-RS 2 Client API in Liberty and Bluemix

I’m a big fan of JAX-RS 2.0 Client API, a part of Java EE 7 specification. They make writing stuff that depends on external REST services really easy on JVM. If you don’t know about the client API, you should definitely check out my recent tutorial for JAX-RS Client APIs.

I just started a project to create clean well typed Java APIs for Watson services) available via Bluemix. It’s a perfect task for the JAX-RS 2 Client API. Although the default web server in Bluemix, WebSphere Liberty, is not yet a certified Java EE 7 server, you can actually already use many of the goodies in Java EE 7, including JAX-RS 2.

Enable JAX-RS 2 in Liberty

To enable those for your application, you should get familiar with your Liberty server’s server.xml file. You can find it from your development server’s usr/servers/defaultServer/ directory or via IDE. There you need to add jax-rs-2.0 to the section. You should note that it also depends on some other newer API versions, so in case your feature manager contains other older features, there might appear conflicts. In my example application, I have the following dependencies enabled:

<feature>localConnector-1.0</feature>
<feature>jaxrs-2.0</feature>
<feature>ejbLite-3.1</feature>
<feature>cdi-1.0</feature>
<feature>jndi-1.0</feature>
<feature>managedBeans-1.0</feature>
<feature>jsf-2.0</feature>

Add the API to your project

Now Liberty provides the newer version of JAX-RS API, but you still need to provide the API also for your application. I did this by brutally adding the whole Java EE 7 API to my project’s pom.xml:

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

Eclipse might now become a bit picky to deploy the application to Liberty, but in IntelliJ it works flawlessly. If you can’t make it work with Eclipse, try adding only the JAX-RS 2 API, instead the whole Java EE 7 specification.

Configure the object mapper

The default object mapper in Liberty uses a bit older version of Jackson. In case you are building a modern app with modern JAX-RS 2, you might want to use a newer version. Luckily, you can pretty easily configure the object mapper used by your Client instance. You can just manually instantiate a Jackson 2 JacksonJaxbJsonProvider and register that in your ClientBuilder. I’m using CDI in my example, so it was really handy to just create the following producer:

private JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();

@Produces
@Dependent
public Client createJaxRsClient() {
    return ClientBuilder.newBuilder()
            .register(provider)
            .build();
}

Deploying to Bluemix

The most tricky part is probably making the deployment work with Bluemix. Bluemix has a rather new version of Liberty Profile, but in case you want to use the beta features, you cannot just use the basic cf push my-app -p target/*.war. You’ll need to set IBM_LIBERTY_BETA environment variable to true and somehow provide the server.xml file that defines the feature set you wish to use.

To set the environment variable, you can simply issue the following cf command:

cf set-env <your-server> IBM_LIBERTY_BETA true

To package the server.xml I decided to save the server.xml “template” (with feature definitions and war file definition), to src/main/libertyserver. Then I created a small assembly trick (assembly.xml + plugin to pom.xml) that builds a deployable directory layout with the target/libertyserver/server.xml file and the war file in target/libertyserver/apps/myapp.war. The Bluemix buildpack will then merge the server.xml configs with those that it defines and deploy the war file. Then you can after mvn install just use the following command:

cf push <your-watson-demo-server> -p target/liberty-bluemix/liberty

Summary

The fluent JAX-RS 2 API is reality today and you can pretty easily use the version provided by the latest Liberty beta releases, also in the Bluemix. It is a really handy API to accessing REST services, such as Watson APIs in Bluemix. Once I got the setup right, implementing APIs is now really easy, in case something is missing from my project, I’m really happy to get pull requests for new features.

To get a simple example of such a setup, check out my recently started project for Watson Java APIs. That might also be a good basis for your Vaadin + Bluemix Challence!

Java API to Watson services

Browsersync and JRebel for keeping you in flow

Browsersync is a helpful utility for automatically reloading browser windows when making modifications to your application and also reflecting browser events between multiple browsers. This can be really helpful when testing your application in multiple browsers while developing.

To get Browsersync working with Vaadin, one can use JRebel to automatically redeploy code modifications to server and then have Browsersync to notify listening browsers that they should reload the page. The trick for connecting Browsersync to JRebel is to have it watch ~/.jrebel/javarebel.stats file that is updated by JRebel after each reload. For theme development you might also want to listen for your scss files and let Vaadin handle SASS recompilation on the fly.

Here is how to start Browsersync on OSX for an app deployed to localhost:8080:

browser-sync start --proxy="localhost:8080" --files="$HOME/.jrebel/javarebel.stats"

For a demo, see the video below.

Using Vaadin Grid

Last week we released one of the most important components in the 7.4 version of the framework - the Grid. If you haven’t taken a look at it yet, I can tell you that there are quite a few features that you can use to present and tune to get your data on the screen.

Like you know, Grid is now a part of the open source framework and free to use under Apache 2 license. To help you get started with it, we wanted to give you some code snippets to visualize how it’s used.

Create and show a data grid

Create an empty Grid with a caption and add it to your layout.  Here we want to reserve most of the space in VerticalLayout for the grid:

Grid grid = new Grid("My data grid");
layout.addComponent(grid);
grid.setSizeFull();
layout.setExpandRatio(grid, 1);

There are alternative constructors for binding the Container data source at the same time. Check out the Grid Javadocs for more details.

Adding data

The most simple way of adding data is to just add some rows:

grid.addRow("com.vaadin", "vaadin-server", "7.4.0");
grid.addRow("com.vaadin", "vaadin-client-compiled", "7.4.0");

You already guessed that this adds two rows with three columns to the data grid, but you can go further by binding containers as data source:

final BeanItemContainer<Person> ds = 
    new BeanItemContainer<Person>(Person.class, personList);
Grid grid = new Grid("Employees", ds);
layout.addComponent(grid);

Of course you can use other (your favorite) containers, from LazyQueryContainer, CollectionContainer to ListContainer, and your own custom ones.

Configuring columns

Now you have something to show. But maybe not all. If your Person objects have nested POJOs, they don’t look that nice, but fortunately you can easily expand those:

ds.addNestedContainerBean("address");

Setting the column order is equally as easy:

grid.setColumnOrder("firstName", "lastName", "salary",
    "address.streetAddress", "address.city", "address.country");

You can also set sizes for individual columns. Just grab the column handle and configure:

grid.getColumn("salary").setExpandRatio(1); // take all available

And you can also set the minimum width for a column:

grid.getColumn("salary").setMinimumWidth(200); // can expand

If you have too many columns to be visible at once, you can have some columns fixed so that they are kept visible all the time.

grid.setFrozenColumnCount(2);

Headers and Footers

While data is the most important thing, it is also important to make it meaningful. Good headers and titles help to bring meaning to your data.

HeaderRow row = grid.prependHeaderRow();
row.join("firstName", "lastName").setHtml("<b>Full name</b>");

As you can see, the HTML can be used to emphasize things.

And the same goes for footers. Display aggregate values, totals, averages or just some text in the end of the data grid:

FooterRow footer = grid.appendFooterRow();
footer.getCell("salary").setText("avg: 1528.55");

Custom data presentation

Sometimes custom data presentation is as easy as binding data, but most typically your data does not match the presentation you want to have. Here is what you can do:

grid.getColumn("salary").setRenderer(new ProgressBarRenderer(),
               new BigDecimalToDoubleConverter());

What happens here is that a “renderer” is used to present column values. You can use one of the built in renderers and converters, or simply create your own special converter:

grid.getColumn("busy")
    .setConverter(new BooleanTrafficLight())
    .setRenderer(new HtmlRenderer());

Notice the fluent API implementation. Here a colored dot is presented instead of the underlying boolean value.

Selecting rows

Primarily you present long (or short) lists of data with the data grid, let the user select something there and receive an event as he or she makes the selection:

grid.setSelectionMode(SelectionMode.SINGLE);
grid.addSelectionListener(new SelectionListener() {

@Override
   public void select(SelectionEvent event) {
       Notification.show("Select row: "+grid.getSelectedRow());
   }
});

You can choose from NONE, SINGLE and MULTI here and receive an event when the selection changes.

Inline editing

Using editor capabilities, you can let the users edit the data in place:

grid.setEditorEnabled(true);
grid.setEditorSaveCaption("Save my data, please!");

While this would already make the data editable, the defaults might not be enough for your data types. Then you can create your own forms:

final MyForm form = new MyForm();
layout.addComponent(form);
grid.addSelectionListener(new SelectionListener() {

    @Override
    public void select(SelectionEvent event) {
        BeanItem<Person> item = ds.getItem(grid.getSelectedRow());
        form.fieldGroup.setItemDataSource(item);
    }
});

And then create a simple form of your own - TextFields, DateFields, Sliders,... whatever you might need there. Here we use the GridLayout (just a layout, not to be confused with the Grid itself) to present a form of three columns:

public class MyForm extends GridLayout {

    public BeanFieldGroup<Person> fieldGroup =
        new BeanFieldGroup<Person>(Person.class);

    private TextField firstName, lastName, salary;

    public MyForm() {
       super(3, 1);
       setSpacing(true);
       fieldGroup.buildAndBindMemberFields(this);
       addComponents(firstName, lastName, salary);
       space();
       addComponent(new Button("Save", new ClickListener() {

           @Override
           public void buttonClick(ClickEvent event) {
               try {
                   fieldGroup.commit();
               } catch (CommitException e) {
                   //TODO: Say and do something meaningful
               }
           }
       }));

       addComponent(new Button("Cancel", new ClickListener() {

           @Override
           public void buttonClick(ClickEvent event) {
               fieldGroup.discard();
           }
       }));
   }
}

With this, you already have a data grid driven CRUD application in your hands. Enjoy Java’s benefits and refactor and rename it to your needs.

Read more

This was just a small glimpse to what Vaadin Grid has to offer. There is much more you can achieve, with styling, filtering and sorting. Take a look at the developer guide, wiki and Javadocs for more.

Visit vaadin.com/grid