Developing a cross-platform application for mobiles and desktops with Aerogear

is a collection of examples, tutorials and best practices to develop mobile clients integrated with JBoss middleware. It aims at providing solutions for mobile clients to deal with typical requirements in enterprise applications, such as security and availability. Such mobile applications range from native clients (e.g. Android, iOS) via hybrid apps (with native and web components) to pure web apps (providing the highest portability but generally being less adapted to the target environment). In this post, we focus on a web-based mobile client and demonstrate how to develop a simple blog application where users can create and comment on blog posts.

Scope of the demo and relation to Aerogear

Mobile-Blog is a cross platform application which allows users to write and comment on blog posts. The client is written in HTML5 and JavaScript while the server application runs on JBoss AS7. The application demonstrates the following concepts:

  • client-server communication using Ajax calls over a REST API via JSON
  • automated execution of tests during the Maven build process, including Needle and Arquillian tests on the server and Jasmine tests for the client JavaScript
  • modularization of client-side JavaScript
  • simple device detection to differentiate between mobile and desktop clients
  • separate frontends for mobile and desktop clients
  • server deployment to the cloud using Redhat’s Openshift platform

The application is to be seen as a representative for more complex mobile applications. As such, modularization and testing is a concern of particular importance. While it would have been possible to write one JavaScript file for the client part of this application, larger projects quickly become difficult to maintain. The integration of all types of tests into the build process is a necessity to test the application in continuous integration environments.

Overview of the application

The initial screens of the desktop and welcome screen of both layouts can be seen here:

The mobile-blog-web application consists of two different layouts: A mobile interface for small touch displays and a desktop interface for mouse-based interaction and big resolutions. We did not follow the common approach of handling different layouts ad-hoc in the respective HTML and JavaScript files. Instead we use two separate layouts. Why? While CSS and JavaScript allow for mighty adaptions of UIs based on device detection, it is important to note that desktop and mobile interfaces are very different. Mobile interaction is based on touch and swipe events while a desktop interface is commonly used via mouse and keyboard. Moreover, the reduced screen size on mobiles will lead either to omission of information and functionality presented on desktop interfaces or to distribution of content from one desktop page across several mobile screens. While adaption of a desktop interface to mobile can still make sense, a distinct mobile interface offers higher adaption with the possibility of an app-like appearance, at the cost of increased effort.

The application consists of multiple Maven modules:

  • mobile-blog-ejb: The data access module, contains DAO beans for database operations
  • mobile-blog-jpa: The model package containing JPA/JSON annotated entities
  • mobile-blog-rest: The service package, contains REST annotated services
  • mobile-blog-web: The client package, contains the HTML/JavaScript files and generates the WAR file

The code for this application ist on Github. After cloning, just build it with

mvn install

as usual. After the build is complete, the web-archive under mobile-blog-web/target is ready to be deployed to the application server.

Client

Native apps usually offer the best performance and user experience. They integrate well within the target environment and share the platform look&feel the user is familiar with. Web-based apps on the other hand offer the possibility to reuse it on multiple platforms, iOS and Android in particular.

This example goes for the web-based approach, where we face the situation of having a huge variety of frameworks to choose from. Well-known candidates are JQuery Mobile and Sencha Touch. The former still suffers performance problems on Android (which is a big factor considering that we should aim for at least iOS and Android), while the latter requires a commercial license to be used for closed-source applications (which is free in most cases, but nonetheless a factor to consider). In this example, we rely on the Jo framework to define the UI and on zepto.js as a lightweight jQuery alternative.

The JavaScript code is divided between a frontend part (which is further divided into mobile/desktop) and the backend (which is used by both mobile and desktop layouts). Each screen in the application is composed of Jo widgets and stored in a separate JavaScript file. Here is the code of the list of blog posts shown in the screenshot above.

var init = function() {
   view = new joCard([
      new joTitle("Blog Post Demo"),
      new joGroup(
         new joFlexcol([
            new joButton('Add Post').selectEvent.subscribe(
                  onAddPostClicked),
            new joDivider(),
            new joHTML("<div id='blogEntryList' />")
         ])
      )
   ]);
};

The layout is written in JavaScript and not HTML5. Events like onAddPostClicked bound to the widgets call the backend which sends out Ajax calls to the server. The JSON response is inserted into UI templates with utility methods provided by the Underscore.js library.

To test JavaScript functionality we use Jasmine, a behaviour-driven test and mocking framework. Tests written with Jasmine can be integrated into the Maven build process with the jasmine-maven-plugin. A typical test would be to check if the list of blog entries is properly updated after receiving a response to an Ajax call:

it("updates a given node with the list of blog entries", function() {
   spyOn($, "ajax").andCallFake(function(params) {
      params.success(responseMock);
   });
   var node = $('<div />');
   App.BlogEntryFrontend.updateWithBlogList(node);
   expect(node.children().size()).toBe(2);
});

The spyOn function of Jasmine is used to mock the Ajax call that would normally occur during App.BlogEntryFrontend.updateWithBlogList(node) and instead calls the success callback with a responseMock that we define ourselves, enabling testing the UI logic without a server.

The server side

On the server side we are using Java EE 6 technologies, e.g. EJB 3.1 lite, JPA or CDI, and the JBoss EAP6 respectively JBoss AS7 as runtime environment.

The application, as already mentioned, consists of several Maven modules. Each module represents a layer of the application. The mobile-blog-jpa module contains the JPA entities for our persistent data. The entities using standard JPA annotations for mapping the java objects to the underling database. This layer defines also the constraints of the domain model with the Bean Validation standard. Bean Validation (JSR 303) defines a metadata model and API for the validation of data. It separates the constraint definition by using annotations and validation implementations. The JSR provides a set of built-in constraint definitions like @NotNull, @Min and @Max, or @Pattern for matching a regular expression, etc. The validation is reused across the different layers of the application.

For the business logic we use Enterprise Java Beans (EJB) components. These components are located in the mobile-blog-ejb module. The layer includes the data access logic for the domain model. Each data access component inherits from a generic base class. The base class provides common operations such as loading and saving entities. One of the advantages of using EJB components is that the invocations by convention are associated with a JTA transaction.

All the implementations of these layers are tested with the Needle framework. Needle is a lightweight framework for testing Java EE components outside of the container in isolation. It reduces the test setup code by analysing dependencies and automatic injection of mock objects.

The clients of our application are pure HTML and JavaScript clients. This means that the servers and clients are distributed. Contrary to a JSF application, where the views are rendered on the server, we cannot access the server components of the application directly via the expression language. Therefore we use RESTful endpoints on the server side. These endpoints are implemented in the mobile-blog-rest module as EJB components and exposed as RESTful web service resources by annotating the component with the standard JAX-RS annotations. The HTTP requests will dispatched to the corresponding method and the return value is automatically converted to the accepted representation of the client, if the accepted type of the request is supported of the requested endpoint.

At this point we want to test the RESTful endpoints integrated with the application server. With the Arquillian integration test framework we can manage the lifecycle of the container and deploy the necessary resources as a ShrinkWrap archive to the container. To invoke the endpoints we are using the RESTEasy JAX-RS client framework. This client-side framework allows us to create outgoing HTTP requests to the server side endpoints, the marshalling of request entity and the validation of the response.

Deploying the application on Openshift

Openshift is the Platform as a Service offering from RedHat. It makes deployments into the cloud easy. With only a few steps we can deploy our sample application to Openshift for free. First we need to sing up a free account on https://openshift.redhat.com/, setup a domain and manage our public SSH key.

There are several tools to create and manage applications e.g. the web console, command line tool, JBoss Tools or JBoss Forge. However, to deploy our application we will use the command line tool. An installation instruction for different operating systems is described in the getting started guide.

The next step is to create an application with the command below. The first argument is our application name and the second argument is the type of the application. We want to deploy our Java EE application on the JBoss Enterprise Application Platform 6. There are also other types available, e.g. JBoss AS 7, Ruby, PHP, etc.

$rhc app create –a mobile –t jbosseap-6.0
Password: ********
Creating application: mobile in akquinet
Now your new domain name is being propagated worldwide (this might take a minute)...
mobile published: http://mobile-akquinet.rhcloud.com/
git url: ssh://1a15942c018e4644a235aa08000d7889@mobile-akquinet.rhcloud.com/~/git/mobile.git/
Successfully created application: mobile

With that command we get an EAP6 application server instance and a git repository for our application.

Instead of the H2 in-memory database we want to use a PostgreSQL database. For that we need to add a cartridge to the application with the following command. Cartridges are components for additional capabilities, like as database or build system.

$ rhc app cartridge add -a mobile -c postgresql-8.4
Password: ********

RESULT:

PostgreSQL 8.4 database added. Please make note of these credentials:
Root User: admin
Root Password: *******
Database Name: mobile

Connection URL: postgresql://127.10.125.1:5432/

Now we can deploy the application, by adding the source to the GIT repository.

$ cd mobile/
$ git remote add upstream -m master git@github.com:akquinet/mobile-blog.git
$ git pull -s recursive -X theirs upstream master
$ git push

On the command line, we see that our application is built and then deployed to the EAP6 instance. This takes a few minutes. However, after that our application is available under http://mobile-akquinet.rhcloud.com.

Conclusion

Summary

We have shown how a mobile web application with a JBoss AS7 backend can be properly modularized. This is a requirement for larger applications or distributed development which forbids monolitic source files.

Furthermore we integrated both unit tests for JavaScript as well as Arquillian integration tests into the Maven build process which allows us to use continuous integration servers during development.

Finally the application can be used as a template of the full stack necessary for a mobile web application with an application server. It also hints on how to extend existing applications with mobile clients by adding a REST layer on top of existing services.

Future work

The login is currently not handled properly. Although the credentials are checked against the server on login, they are not enforced during later REST calls. Furthermore, the “login” is lost as soon as the page is refreshed. We would like to add proper authentication for all server calls and provide a valid session management via stored cookies.

Another interesting extension would be the implementation of push notifications which refreshes the list of blog posts as soon as someone creates a new post. For the mobile client there are different possible directions, for example a native service on Android could provide a mechanism to display new blog posts in the notification tray. Alternatively, push could be implemented via JavaScript to refresh the page in the browser.

Feel free to contact us via email if you have questions or remarks:

enrico.biermann [at] akquinet.de
philipp.kumar [at] akquinet.de

One Response to Developing a cross-platform application for mobiles and desktops with Aerogear

  1. Rubye says:

    Since his “jobs czar” praised Germany for the actuality that “government and organization [do the job] as a pack.
    In 1907, James Murray Spangler, built a vacuum cleaner with baggage to seize grime and
    debris, boosting kitchen area layout. A single of the fancy important things to
    do with modest microwave is reheating espresso without mess at
    a ideal temperature.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 202 other followers

%d bloggers like this: