Showing posts with label jsf. Show all posts
Showing posts with label jsf. Show all posts

Wednesday, February 20, 2013

Server Push using Atmosphere (Glassfish + PrimeFaces)

Server Push is described as a mechanism in which the server initiates a transaction to a client (http://en.wikipedia.org/wiki/Push_technology). This mechanism has various interesting implementations which improve the options for interaction on a website such as an online chatbox (http://www.primefaces.org/showcase/push/chat.jsf) in which users are informed of new logins and messages.

There are various technologies which implement mechanisms to achieve the experience of server push such as;

- Native Comet (The WebServer has API for Comet)
- Native WebSockets (The WebServer has API for WebSocket)
- WebSockets
- Long-Polling
- Http Streaming
- JSONP
- Server-Sent Events

I will not go into detail for each of these options.

Atmosphere

Which technology is a wise choice to follow and implement? Every method has it's own drawbacks. I myself have considered implementing a custom Long-polling mechanism in the past. WebSockets is new and gaining popularity ('hip' in dutch ;), however a lot of browsers do not natively support it yet. See a list on; http://stackoverflow.com/questions/1253683/what-browsers-support-html5-websocket-api. When WebSockets is not supported you want the option to fall back on more primitive options. This would however require implementing different technologies and thus more work. Luckily there are frameworks which provide an abstraction to the technology based on what the server and client support. Atmosphere is one of those frameworks; https://github.com/Atmosphere/atmosphere. Atmosphere provides a wide array of support options for server and clientside of the server push mechanism; https://github.com/Atmosphere/atmosphere/wiki/Supported-WebServers-and-Browsers. Also when using Atmosphere, future technologies will most likely not require more rework then an Atmosphere upgrade.

Implementation

I wanted to create a website which provided chat support and some other options. I didn't want to have to click a refresh button to update my screen but I wanted events triggered by clients to lead to updates; I wanted a server push mechanism. I chose my development environment to be Netbeans, my server to be Glassfish and my JSF framework to be PrimeFaces (see http://javaoraclesoa.blogspot.nl/2013/02/a-simple-j2ee-webapplication-netbeans.html). Glassfish has good support options for server push mechanisms; all the mentioned technologies can be used with the latest version of Glassfish. PrimeFaces natively supports Atmosphere (https://github.com/Atmosphere/atmosphere/wiki/Atmosphere-PlugIns-and-Extensions).

Glassfish Comet support

At first I got the following errors in Glassfish;

SEVERE: AtmosphereFramework exception
java.lang.IllegalStateException: Make sure you have enabled Comet or make sure the Thread invoking that method is the same as the Servlet.service() Thread.
at com.sun.grizzly.comet.CometContext.addCometHandler(CometContext.java:295)
at com.sun.grizzly.comet.CometContext.addCometHandler(CometContext.java:314)
at org.atmosphere.container.GrizzlyCometSupport.suspend(GrizzlyCometSupport.java:139)
at org.atmosphere.container.GrizzlyCometSupport.service(GrizzlyCometSupport.java:121)
at org.atmosphere.container.GlassFishWebSocketSupport.service(GlassFishWebSocketSupport.java:70)

My first guess whas that I needed to enable Comet support. I looked it up and found the following;

When I activated it and restarted the server however, the setting was lost. I found the following bug; http://markmail.org/message/3fo3tyo72pew4jv4. The Comet support setting was not always persisted. I found some other options to try; using asadmin to add the option (http://blog.eisele.net/2012/09/primefaces-push-with-atmosphere-on.html) and manually editing the domain.xml. Both didn't fix my problem. My Glassfish server was a Netbeans embedded version. Then I found the following checkbox and the problem was fixed.


PrimeFaces implementation

All the code required was the following in the JSF file;

<p:socket onMessage="handleMessage" channel="/messages" />
<p:remoteCommand name="updateMessagesTable" actionListener="#{messageBean.loadMessages}" update="MessagesDataTable"/>
            
<script type="text/javascript">
                function handleMessage(data) {
                    updateMessagesTable();
                }
</script>

The following in the web.xml file;

    <servlet>
        <servlet-name>Push Servlet</servlet-name>
        <servlet-class>org.primefaces.push.PushServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Push Servlet</servlet-name>
        <url-pattern>/primepush/*</url-pattern>
    </servlet-mapping>

And the following in the backing bean of the JSF page;

    private void doPushUpdate() {
        PushContext pushContext = PushContextFactory.getDefault().getPushContext();
        pushContext.push("/messages", "update");
    }

How does this work?

In the messageBean, when the doPushUpdate function is called, all clients receive asynchronous updates on the specified channel. This triggers them to update the messages table.

<p:socket onMessage="handleMessage" channel="/messages" /> in the JSF page responds to a message on the channel /messages. It calls the Javascript function handleMessage when an asynchronous server push event is received. The line; <p:remoteCommand name="updateMessagesTable" actionListener="#{messageBean.loadMessages}" update="MessagesDataTable"/> makes available a Javascript function called updateMessagesTable() which calls the messageBean function loadMessages after which it updates my MessagesDataTable. The Javascript function handleMessage calls the updateMessagesTable function and in effect the messageBean function. The handleMessage function is not required since I could have called the updateMessagesTable function directly, but I wanted a location at which I could do something in Javascript with the received message.

How does it look?

Keep in mind that this is my first play with server push and PrimeFaces. I was pretty satisfied with the result and the relative ease at which it was achieved. After every message all clients get updated. If you want to know what PrimeFaces is capable of, check out their impressive showcase (http://www.primefaces.org/showcase).


What more could you want?

I could have dynamically updated the table or other portions of the site instead of refreshing it completely. Also I have not implemented a lazy loading mechanism; http://www.primefaces.org/showcase/ui/datatableLazy.jsf

The potential usages of server push mechanisms are numerous. Server push allows communication with a server as mediator. For example it can be implemented to allow direct communication with website visitors or allows visitors to immediately interact with each other. It also allows external events (happening on the server) to influence what visitors get to see on your site on the fly.

The code can be downloaded here

Tuesday, February 12, 2013

A simple J2EE webapplication; Netbeans + PrimeFaces + JPA

Webapplications are not my area of expertise, but once in a while I like to try some things to see how easy it would be to get something done. This time I wanted a webinterface which would be able to get/display data from a database and put stuff back in. I wanted a solution which would be quick to develop and stable in an enterprise environment. I chose to use open source software for this. I am however impatient and want quick results.

Development environment

I was looking for a development environment which would allow me to be productive; had good support for webdevelopment (wizards for generating code for me) and Maven (for easy dependency management). I started out with Eclipse. I followed the following tutorial to get it installed in Ubuntu; https://help.ubuntu.com/community/EclipseIDE. Ubuntu comes packaged with an old Eclipse version so to get the newest version working, some things needed to be done. After that I installed the Maven support and the WebToolKit (WTK) plugin. After much fiddling with the plugins, I decided to quit trying to get this to work; I couldn't get it working quickly enough and I would probably encounter other issues along the way when continuing on this path.

My second choice for IDE was Netbeans. I installed the latest version and Maven, JSF integration, Glassfish integration worked out of the box without any work. I was pleased with Netbeans.

Front-end framework

For the front-end I decided on a JSF implementation which is seen quite often nowadays. I took a look at the following comparison of JSF frameworks; http://www.mastertheboss.com/richfaces/primefaces-vs-richfaces-vs-icefaces. Based on the comparison and my bad experiences with Richfaces and server push, I decided to go with Primefaces (try something new). It had jQuery code integrated which I also liked (see for example; http://blog.primefaces.org/?p=2226). PrimeFaces has a large set of ready to use examples; http://www.primefaces.org/showcase/ui/home.jsf. This would save me a lot of work.

Back-end integration

For the database I wanted to have as little work as possible. I don't like to program things like relations, constraints, data structures, etc in the database; I was developing a web-application and the data-model, implemented as Java entities, should be sufficient definition. I chose to use the Java Persistence API (JPA) in combination with the pre-installed/configured Derby database. For the JPA implementation I chose EclipseLink since it was selected by default. Hibernate was also one of the options. I didn't do any research on the best choice for me since I wanted to quickly start developing and this worked out of the box.

Developing

The EntityManager and EntityManagerFactory

I read several tutorials and went developing. I started out with different tutorials such as  http://hendrosteven.wordpress.com/2008/03/06/simple-jpa-application-with-netbeans/ and http://www.objectdb.com/tutorial/jpa/netbeans/web. In these tutorials I encountered two very interesting and much discussed classes; EntityManagerFactory and EntityManager. These two classes make it possible to link the data model entities to the persistent storage.

Then it became a little bit more complicated. Where should I do things like starting a transaction? What should be the scope of my transaction? How should I manage the lifecycle of the EntityManager and the EntityManagerFactory? Since the transaction code could be reused among entities I decided not to put it in my entity classes. I first created an EntityUtils class (replace entity with a specific entity name) which would do entity management such as starting transactions, deleting, creating entities, performing queries on the entities. Then I found the following list of patterns; http://blog.xebia.com/2009/07/13/jpa-implementation-patterns-wrap-up/. My EntityUtils class was actually a DAO! (Data Access Object). I refactored my EntityUtils class and created a common (using type-variables) abstract class for DAO's. I still had to manually manage the transactions though.

Then I found the following tutorial;http://netbeans.org/kb/docs/javaee/javaee-gettingstarted.html. I could generate almost all the code I had previously written. Manual transaction management was not required. The DAO was however called ServiceFacade. Most likely because of the different role the class has when comparing for example Sevlet implementations to JSF implementations. Based on this last tutorial I could finish my webapplication and had an efficient mechanism to generate most of the code required to use the database from my JSF application.

I have not provided my application as an example for download since the tutorial mentioned would provide a better description. Also I will need to expand the application a little further to convince myself I'm developing efficient reusable stable code.

Conclusion

These conclusions are based on my personal experiences.

- use Netbeans instead of Eclipse in you want more functionality (being not specific here on purpose) to work out of the box
- checkout different frameworks for your JSF implementation. PrimeFaces has a lot of easily usable online examples and jQuery integration
- start a research on the EntityManager and EntityManagerFactory. using them efficiently in a Servlet differs from an efficient implementation in a JSF page.
- there is a lot of information available. getting to the relevant parts required effort

The following document contains a lot of information on J2EE; http://docs.oracle.com/javaee/6/tutorial/doc/javaeetutorial6.pdf. To get something working quickly however http://netbeans.org/kb/docs/javaee/javaee-gettingstarted.html is recommended.