Red Hat

In Relation To Rich Faces

In Relation To Rich Faces

RichFaces 4.1.0.Final Released!

Posted by Jay Balunas    |       |    Tagged as JSF Rich Faces Seam

In my previous blog about Brian Leathem becoming the RichFaces project lead, I mentioned that the release of RichFaces 4.1 is imminent. It is not longer imminent, but upon us!

I'm very happy to say that today Brian announced the release of RichFaces 4.1.0.Final!! This is a great release for RichFace and JSF, please take a look at Brian's blog for all the details, and keep an eye out for some follow up blogs highlighting the new features!

Changing Of The Guard With RichFaces 4.1

Posted by Jay Balunas    |       |    Tagged as JSF Rich Faces Seam

The release of RichFaces 4.1 is imminent and with it brings some great advancements to the project and JSF! Among the most notable are additional mobile support, push upgrades, new components, and more.

Recently however, I’ve been focusing on more general mobile and HTML5 initiatives. You can see some of what I’ve been up to in the webinar I had Wednesday Dec. 7th on getting started with HTML5/Mobile development with JBoss (recording will be available soon).

This has meant that I’ve not had the time to dedicate to RichFaces that it deserves, and so I’m thrilled that we have an engineer and leader like Brian Leathem who has agreed to lead the project into the future!! He is already the seam-faces project lead, and has been a critical member of the RichFaces for some time!

Brian and the rest of the RichFaces team have not only done a great job on RichFaces 4.1, but also have some great plans for the future of RichFaces. Brian has started to outline these to start the discussions. This is only going to pick up steam once 4.1 is out!!

I’m not just going to disappear though, mobile and HTML5 are certainly an integral part of RichFaces! Keep an eye out in this space for more from me and JBoss about all aspects of mobile application development including mobile web, hybrid, and native techniques.

I wanted to take a moment and thank the RichFaces team and community! I’m could not be more proud of the people that use and develop RichFaces. Through our forums, weekly meetings, and now github we’ve seen a huge increase in contributors, users, and colleagues. To all of you:

We're going to dive down into the rabbit hole, and follow up on Wesley Hales great video on deploying the mobile web optimized RichFaces TweetStream application to Red Hat's new, free PaaS offering OpenShift Express complete with JBoss AS 7 under the hood!

Whats Been Covered

There has already been a lot of coverage on OpenShift, and the mobile web optimized TweetStream app. So I'm not going to cover old ground. Check out these blogs and videos:

OpenShift Express Updates

The RichFaces team is in the process of migrating our RichFaces Showcase application from Google App Engine to OpenShift Express, we'll have it ready soon. OpenShift offers a number of benefits over GAE, it is a real Java EE container, supports RichFaces push and has a much less restrictive API

Like many other free PaaS offerings OpenShift Express does have a few limitations that you need to consider. The most important ones for our application are limited threads, and JMS support. Note that all of these go away when you move up to OpenShift Flex!

RichFaces Push streamlined

When RichFaces 4.0.0.Final was released our push component was tied to JMS. This provides excellent enterprise level messaging capabilities, but unfortunately requires some setup to use. Since JMS is not provided by Express out of the box we needed to make some changes. So for 4.1.0 we are adding in a few options!

Starting with RichFaces 4.1.0.M1 RichFace Push can be decoupled from JMS. All that is needed is to set a context param:

<context-param>
    <param-name>org.richfaces.push.jms.disable</param-name>
    <param-value>true</param-value>
</context-param>

This will switch push to using an internal message queue. Look for further blogs, and documentation on this in the future. This is also one step closer to our plan to support CDI events as part of RichFaces Push.

Atmosphere updates on the way

Another change that was needed was moving to a snapshot version of Atmosphere. Atmosphere had a bug where it was creating a new thread for each request - ouch! Since OpenShift Express has limited threads available we needed a way around this.

Thankfully this issue was fixed in the Atmosphere 0.8-SNAPSHOT branch. This version of Atmosphere is due to be released in August, and RichFaces will use it by default once it is (likely in the 4.1.0.M2 release).

For now - if you are working on your own RichFaces push application and deploying to Express you'll need to override the Atmosphere version. This is simple enough with Maven, just add the following to your pom:

<dependency>
  <groupId>org.atmosphere</groupId>
  <artifactId>atmosphere-runtime</artifactId>
  <version>0.8-SNAPSHOT</version>
</dependency>

Infinispan cache LOCAL support

As was discussed in some of the linked blogs, the TweetStream application uses Infinispan under the covers to provide caching for the tweet data that we process. Infinispan in cluster mode uses jGroups to provide advanced communication support.

The problem here is the threading that accompanies this. For TweetStream it is important to make sure that you are using Infinispan in LOCAL mode. The latest TweetStream source has been updated to use the LOCAL cache.

Where to go from here

Now that we've gone over updates that are needed to take advantage of OpenShift Express I encourage you do give it a shot on your own. The source code is in the TweetStream git repo. Just follow the readme to setup and build it. Then deploy following the instructions in Wesley's video.

There will be more JBoss and OpenShift blogs and videos coming out, so stay tuned and check out JBoss and OpenShift page for the latest news.

[OpenShift Express] [JBoss OpenShift News] [OpenShift Twitter] [TweetStream git Repo] [RichFaces Twitter]

The JBoss World opening Keynote featured one of the best keynote demonstrations I've ever seen!! Part of that demonstration included a RichFaces application customized for the mobile web call TweetStream. We are going to talk about that app, why it works so well for mobile web development, and how you can get it running on your machine.

The entire JBoss World demonstration included many JBoss projects; such as JBoss AS, Infinispan, Hibernate OGM, CDI, and Errai. A video of the keynote & demo is available through the image on the left. The demo starts around 35:15 minutes in. And yes that WAS my real iPad/iPhone password :-)

The latest JBoss Assylum also features many of the developers giving behind the scenes perspective and humor. Each project will be providing blogs and code for its own part. You can get the latest at the JBoss World Keynote 2011 landing page, and follow along with the #jbwkeynote2011 twitter hashtag!

RichFaces TweetStream Application

Wesley Hales and I were looking for an application to show RichFaces 4 on mobile devices for our JUDCon presentation: Filling the Gap: Going Mobile With JBoss Technologies Today. We came up with a simple idea that would be instantly recognizable, allow audience participation, and with just enough UI complexity. It was around this time that JBoss Keynote was being planned, and TweetStream just fit right in!

TweetStream uses twitter4j to search and filter a stream of tweets containing a set of hashtags, and displays them to the user. It also keeps track and calculates the top 10 tweeters, and the top 10 hashtags. It then uses RichFaces Push to keep the UI updated with the latest content across devices.

In front of this Wesley and I built a set of RichFaces 4 views that provide advanced support for different mobile devices. We targeted webkit browsers that run on iPhones, iPads, BlackBerry, and Android devices. Each view is served through a single URL with device detection for a one bookmark solution. We achieved near native behavior using advanced HTML5/CSS3 techniques to process orientation layout changes, transitions, and more.

If you just can't wait to check out the demo on your own machine we have a version of it hosted on RedHat's OpenShift just follow this link http://bit.ly/tweetstream2. The Filling The Gap presentation was also recorded and contains Wesley and I discussing some of the apps details.

Source Code, OAuth, and IDE Integration

Instead of just explaining the various parts all up front lets just jump right into getting the source code, building it, deploying to JBoss AS and integrating it into JBoss Tools. We'll discuss some of the internals below, or is follow up blogs.

note: I'm assuming you have git, Maven, Java 1.6, JBoss AS 6 Final, and JBoss Tools 3.2 for IDE integration

The TweetStream source code is part the RichFaces organization on github.com. You can use git to clone the repo with: git clone git@github.com:richfaces/tweetstream.git. We'll talk about the structure after we get it running.

Twitter4j & OAuth

While we would love to let you use our twitter account credentials, that would not be so good. This means that you'll need to go through the steps outlined in the README to get twitter4j setup.

Twitter has a good step by step process for this on there OAuth page. Once you go through that you'll be able to update the twitter4j.properties file with these values:

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

Once that's done all that is left is deploying the application!

JBoss AS 6

In the base /tweetstream directory run mvn package to build the standalone version of the application. You should now have the file /tweetstream/target/tweetstream.war. Copy this file to the $JBOSS_HOME/server/default/deploy directory.

At this point your can start the server, but I would recommend you start with the $JBOSS_HOME/bin/run.sh -b 0.0.0.0 if you want to access the server from external clients, like your mobile phone ;-)

Once the application starts up you can see it at http://localhost:8080/tweetstream. If you want to try out your smartphone or tablet you may need to modify you firewall to allow port 8080 through. Then access using your tablet, or phone at http://your.ip:8080/tweetstream.

Importing into JBoss Tools

Importing this project into JBoss Tools 3.2 is easy because it uses m2eclipse under the covers. All you need to do is choose File-->Import-->Existing Maven Project, and point it to where you cloned the source code. Eclipse will run through it's normal project import, and in a few minutes have the new project ready to go.

A couple of things to note:

  • Add your JBoss AS 6 server as normal and you can configure TweetStream to be deployed
  • You may see build issues in the /jbw project - I'll explain that in a minute

Structure and Key Files

Now that you have the application running, and hopefully imported into JBoss Tools lets talk about the structure and some of the key areas to look at.

As I alluded to above this application was originally just going to be for Wesley and my JUDCon talk. When it became part of the JBoss World Keynote demo we needed to support two different back-ends. We did this by using the power of CDI, and Maven to create two profiles. A standard profile for JUDCon, and a keynote version. Below is a brief explanation of the various modules:

/tweetstream  #Core application and views
/shared       #Classes files needed across the other two modules
/jbw          #Keynote specific source files to hook into the different backend

The build errors you get in eclipse for the /jbw directory is because of missing dependencies related to the keynote demo. At some point in the near future we'll be releasing the whole keynote demo, but for now Tweetstream is moduler enough to run on its own.

The way we were easily able to shift our backend so easily is a testament to not only JBoss, but to the Java EE as a whole. The pieces fit together well, and with CDI, and JSF we were able to swap in a completely different backend with very little effort.

As I said we'll be following up this blog with deep-dives into the various details, but for now, here are some things to take a look at:

Device detection

We use a great little project called mobileESP to help us with device detection. It is a basic user-agent sniffer that we wrapped in a CDI bean to do our bidding in a class called UserAgentProcess.java. This could be swapped out for any of the other device detection libraries such as the WURLF API.

We take advantage of JSF 2.0 and facelets templating to provide a single point of access per view to act as a dispatcher for different devices. This provides a single bookmark and URL no matter what device you are accessing it from. You can review that in the home.xhtml

Orientations detection and updates

Using CSS 3 @media selectors makes this a breeze. We use this to great effect in for the tablet view. Always keeping the top tweeters, and top hashtags in the best location.

SmartPhone transitions

Making the page handle the page transitions on smartphones was also easier than you'd think. You can review the details in the phoneHome.xhtml file.

Misc

Improvements That Can Be Made

TweetStream was developed quickly and with a singular goal in mind. There are some great opportunities for improvements, future RichFaces components, and more. I would like to encourage anyone who is interested to take look in more detail. Here are some possible ideas for improvements

  • Streamline device detection
  • Customizable search filters
  • Layout components to support transitions
  • RichFaces Mobile Skins
  • Combine, and compress CSS
  • Performance analysis and update
  • Drill-downs on tweets and tags
  • Flush out the desktop version

There are a lot more possibilities, fork it, play, and lets see what you can come up with!! We'll be standardizing and integrating some of these things into RichFaces, and other parts of JBoss so stay tuned!!

Where to go from here

Wesley and I are going to post additional blogs and dig into some of the features just touched on above. All of this should give you a good starting point for your own mobile web application using RichFaces 4 and JBoss! Also, as I mentioned above there are going to be several more blogs related to the JBoss World Keynote demo that will detail Infinispan, Hibernate OGM, the plug computers and more!!

[JBW Keynote Page] [JBW Keynote Twitter] [JBW Asylum] [TweetStream Online] [TweetStream Git Repo] [RichFaces Twitter]

RichFaces 4 - programmatic control of partial processing

Posted by Ilya Shaikovsky    |       |    Tagged as JSF Rich Faces

There is an important feature in RichFaces 4 that get documented at wiki recently and today I want to point you to that article. That article is related to Programmatic control of partial processing in RichFaces 4.

If you working with RichFaces 3.3.x and looking for the same info - do not ignore that page. It's written as comparison of 3.3.x and 4.x functionality so you will see RichFaces 3.3.x methods also!

Questions which are adressed in that article (for both RichFaces 3.3.x and 4.x) listed below. Again all the answers related to programmatical access to PartialViewContext and not just working at component/attributes level.

  • How to add component to set of execute'd ones.
  • How to add component to set of render'ed ones.
  • How to check if current request is Ajax request.
  • How to limit Ajax updates to just set of render'ed components excluding automatically rendered ones.
  • How to append JavaScript event handlers from server side
  • ...more

So look through the article and let RichFaces team know about your experience of using all that stuff. And share your thoughts about anything still missing at User Forum.


[Get updates of my blogs in twitter]

[My jroller.com blog]

RichFaces 4.0.0.Final Released!!

Posted by Jay Balunas    |       |    Tagged as JSF Rich Faces Seam

The RichFaces team and community are happy to announce that RichFaces 4.0.0.Final has been released!! This was a huge effort, but the end result was well worth it. Without further ado, you can download the distribution from our project's download page, and check out our collection of getting started guides including Maven, non-Maven, Ant/Ivy, and GAE. Plus you can now give our components a test drive anytime at our Online Component Showcase demo.

For all the details of what went into this final release please review the jira release notes. We also have the final project release notes for the project available for review.

Why RichFaces?

RichFaces 4 goes beyond simply supporting JavaServer Faces (JSF) 2. It has extended multiple areas of JSF, including usability, performance tuning, dynamic resources, skinning, and component development. This allows users to take full advantage of all the productivity enhancements of JSF 2. Some notable highlights include:

Our Community

In previous blogs I've talk about about how open source communities really thrive on their community. I've talk about how CR releases can stand for "Community Required" because of how important it is to get that feedback. All I can say is that our community stepped up, and continue to impress! We've seen a huge increase in the feedback, and both veterans and new users giving RichFaces 4 a try and helping us to make it to this point.

There are too many to list out here, but you are all appreciated!! Although, I would like to remind everyone that the JBoss Community Recognition voting ends April 2nd. Please check out the candidates from our community and give them a vote!

Our Quality

Closely related to our community and the feedback we get from them, is our focus on testing. At RichFaces we have prided ourselves on the level of testing, and stability that we have achieved. A big part of that is because of the effort our guys put into it.

Test framework development highlights:

  • Metamer - Framework that makes it easy to add new components and test each attribute under different UI templates
  • Ajocado now part of Arquillian which allows type safe Ajax with Selenium
  • Rush Eye now part of Arquillian helps test regressions by doing a visual comparison of results.
  • Partial Google Page Speed and Selenium Integration for client side performance testing

Total Number of Automated Tests: 2350. Multiply this by environment variables like JSF implementation, Application Server, and UI containers and the total number of complete automated tests go to : 2350 x 4 x 2 = 18, 800!! Plus we are adding to it all the time...

Our Documentation

We really wanted to have a focus on complete and quality documentation that would be available to everyone. One of the guys on our team (Sean), really did a great job and focused on the documentation. We have also had some informative additions to our wiki page, and knowledge base from our community, and team.

Want Even More Information

We've got a whole stack of blogs, conference talks, and upcoming publications to keep you busy :-)

What's next

That is a wide open question. We're planning to start on a 4.1 version soon with shorter time-boxed release schedules. We'll be discussing this more on the developer forums and team meetings. This release will likely include a variety of new features such as; Mobile/Tablet specific components, HTML5 extensions, new components like the rich:editor and rich:growl and more. Please join in the discussion, and be part of the future of RichFaces!

In other areas of the project:

  • Series of how-to articles for development with and on the project
  • Mobile development series on how to build for the mobile web with RichFaces 4
  • Add examples, and more details the Migration Guide 3.3 --> 4.0
  • Component Sandbox rules, and wiki page updates to help everyone become a component developer guru
  • Jira reviews from the past, and future

None of this is possible without you though! We want to hear from you, and if you find an issue, have comments or ideas please let us know through our forums, or our project jira. See our Project Calendar and the Meeting Information page for more details, agendas, and minutes if you want to get involved more!

[Project Site] [Downloads] [JIRA] [User Forums] [Design Forums] [RichFaces Twitter]

Getting started with RichFaces 4.0 Push

Posted by Ilya Shaikovsky    |       |    Tagged as Rich Faces

Overview

RichFaces Push allows you to perform realtime client side updates triggered via events from the server side. We integrate with the Atmosphere framework which provides various transport mechanisms according to concrete browser support(Comet, HTML5 WebSockets). On the server events are managed by integrating Java Messaging Service (JMS). This provide enterprise level messaging integration all the way to the browser!

In this blog I will describe our irc-client example application that was created to introduce the RichFaces push features. It provides the following functionality:

  • Connect to the freenode.org IRC server
  • Join a channel with choosen nickname
  • Receive all channel messages (nick change, join, part...)
  • Send messages to the channel
  • Observe the list of joined users with real-time updates

In this blog I'm only going to review the important configuration, and source code snippets from the application. The full source code can be checked out from SVN so you can try it for yourself. Instructions for building and deploying the application is in the readme.txt.

Dependencies

To save time with application setup I have created a starter application using richfaces-archetype-simpleapp archetype. Next we need to update application pom.xml to add Atmosphere fremework dependency. For the client side a4j:push uses jquery-atmosphere.js plugin (added implicitly by the component renderer).

NOTE: that particular sample targeted for JBoss 6 Application Server. So we will use JBoss HornetQ available out of the box. Using RichFaces Push under Tomcat or Jetty requires additional JMS dependencies and configuration code. We will work on maven profiles and additional optional classes for that case also in future releases. At the moment the only place to review that configuration is with our developer demo which configured for tomcat using external HornetQ dependencies and configuration class for its initialization.

We need to add the atmosphere-runtime to the pom.xml. This is only needed if you are using the push component.

<dependency>
    <groupId>org.atmosphere</groupId>
    <artifactId>atmosphere-runtime</artifactId>
</dependency>

Also as the demo shown there provides simple IRC client we added one more dependency:

<dependency>
    <groupId>pircbot</groupId>
    <artifactId>pircbot</artifactId>
    <version>1.4.2</version>
</dependency>

PircBot is a simple framework for writing IRC bots.

Configuring JMS

Lets first discuss why we need JMS at all? Why not just use for example push context object? The answer is pretty straightforward. Usage of JMS at the back-end provides excellent integration with EE containers, and advanced messaging services. It also frees you from managing various entities at your business layer. If you are already using JMS for messaging in your application - you will just continue to send the same messages and you just need to to declare a4j:push at views which should listen that topics.

We assume that you're familiar with JMS so will not provide details here. To learn more about it visit JMS documentation.

Now it is time to configure JMS for our example. We will use JBoss 6 AS for application deployment as mentioned in dependencies section. So we'll use JMS server bundled with JBoss AS. We need to create topics which will be used by Push to check for the messages. Let's start JBoss 6 AS and open http://localhost:8080/admin-console. We will use default admin/admin credentials to log-in. Then click the JMS topics in navigation menu and create new JMS topic with the following settings:

Name: chat

JNDI name: /topic/chat All the others: by default.

In the same form we need to add roles for that topic. For that demo application we will create single role with next parameters:

Name: guest

Send: yes

Consume: yes

create subscriber: yes

delete subscriber: yes

create durable subscriber: yes

delete durable subscriber: yes

IMPORTANT: The last two options are critical for push functionality as we using durable subscriptions in order to be able to receive all the events including ones which were sent while the push was not connected to the server. So if they are set to false - push will not be able to register subscribers.

So here is what you should see after JMS setting done:

That's all. Now we are ready with JMS configuration.

NOTE: if you not familiar with JBoss configuration using admin-console visit JBoss AS Administration Console User Guide.

Web Application Configuration

Now let's add application settings required by RichFaces Push. We need an additional filter and a few context-param's to be added. Here is what we used for that demo application:

<context-param>
    <param-name>org.richfaces.push.jms.connectionUsername</param-name>
    <param-value>guest</param-value>
</context-param>
<context-param>
    <param-name>org.richfaces.push.jms.connectionPassword</param-name>
    <param-value>guest</param-value>
</context-param>
<filter>
    <filter-name>PushFilter</filter-name>
    <filter-class>org.richfaces.webapp.PushFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>PushFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

Let's review those parameters in details. At first we need the PushFilter to be installed and mapped to Faces Servlet. It will handle the push request and serve event using the Atmosphere runtime. And connectionUserName and connectionPassword context parameters are needed in order to defined the credentials used to work with JMS for connecting and subscribing to topics.

Here is the table with all the parameters which could be used in your application:

context-param Name Default value Description
org.richfaces.push.jms.connectionFactory /ConnectionFactory JMS connection factory JNDI name
org.richfaces.push.jms.topicsNamespace /topic used as a root name from which all topics are resolved: i.e. 'chat' topic by default will be looked up via /topics/chat JNDI name.
org.richfaces.push.jms.connectionUsername - Username used for connection and topics creation/listening
org.richfaces.push.jms.connectionPassword - Password used for connection and topics creation/listening

Note: there are also JNDI references to credentials strings available:

  • java:comp/env/org.richfaces.push.jms.connectionUsername
  • java:comp/env/org.richfaces.push.jms.connectionPassword

An alternative to using web.xml definitions is to provide all the parameters using properties file org/richfaces/push.properties.

TopicsContext initialization

Now we need to initialize org.richfaces.application.push.TopicsContext with the JMS topics we will listen for. For this purpose we created a JSF 2 System Event listener which handles PostConstructApplicationEvent:

public class TopicsInitializer implements SystemEventListener {
   public void processEvent(SystemEvent event) throws AbortProcessingException {
       TopicsContext topicsContext = TopicsContext.lookup();
       Topic topic = topicsContext.getOrCreateTopic(new TopicKey("chat"));
       topic.setMessageDataSerializer(DefaultMessageDataSerializer.instance());
       topic.addTopicListener(new SessionTopicListener() {...});
   }
  public boolean isListenerForSource(Object source) {
       return true;
   }
}

and registered it in faces-config:

<application>
    <system-event-listener>
        <system-event-listener-class>org.ircclient.listeners.TopicsInitializer</system-event-listener-class>
        <system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
    </system-event-listener>
</application>

With this we have created new topic in TopicContext with chat name (the same as we defined configuring the JMS).

Actually MessageDataSerializer and TopicListener creation are optional, so let's briefly describe the main idea of these objects.

  • Messages serializer is used to serialize the message to the expected format for passing to the client. By default built-in serializer will serialize the message data to JavaScript.
  • Session topic listener is used to handle subscriptions (pre and post-processing) and unsubscription events. This could be used for example in order to check user permissions prior to connecting to some topic and perform some additional post-processing after some push component successfully attached to topics. In the sample there are just logging used so the code is omitted there.

Application Code

We are done with settings and push initialization stuff, and it's time to actually explore the example code to see how we manage the IRC connections, and how push is used for page updates according to server-side events.

Logging to IRC

This section is not directly related to Push but describes the code used for connection to IRC. Here is the simple page used:

<rich:panel header="Connect to IRC">
    <h:form>
        <rich:messages style=”color:red”/>
            <h:panelGrid columns="2">
                <h:outputText value="Your nickname:" />
                <h:inputText required="true" id="name" value="#{chatBean.userName}" />
                <h:outputText value="Channel:" />
                <h:outputText value="RichFaces" style="font-weight:bold"/>                        
                <h:outputText value="Server:" />
                <h:outputText value="irc.freenode.org" style="font-weight:bold"/>                
            </h:panelGrid>
        <h:commandButton value="Connect" action="#{chatBean.connect}" />
    </h:form>
</rich:panel>

It's rendered as:

Note that for simplicity purposes the channel and server names are using constants. In the future we plan to extend the sample with ability to open multiple channels and so on..

And here is the ChatBean.java used:

@ManagedBean
@SessionScoped
public class ChatBean extends PircBot implements Serializable {
private static final String SERVER_URL = "irc.freenode.org";
private static final int SERVER_PORT = 6667;
private static final String CHANNEL_PREFIX = "#";
private static final String SUBTOPIC_SEPARATOR = "_";
private static final String DEFAULT_CHANNEL = "richfaces";
private String channelName;
private String message;
public String connect() {
       try {
           this.connect(SERVER_URL, SERVER_PORT);
           this.joinChannel(CHANNEL_PREFIX + DEFAULT_CHANNEL);
           channelName = DEFAULT_CHANNEL;
       } catch (NickAlreadyInUseException e) {
           FacesContext.getCurrentInstance().addMessage(null,
               new FacesMessage(FacesMessage.SEVERITY_ERROR, this.getName() + " nick 
               already in use", this.getName()
               + " nick already in use"));
           return null;
       } catch (IOException e) {
           FacesContext.getCurrentInstance().addMessage(null,
               new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sorry, server unresponsive. 
               Try again later.",
               "Sorry, server unresponsible. Try again later."));
           return null;
       } catch (IrcException e) {
           FacesContext.getCurrentInstance().addMessage(null,
               new FacesMessage(FacesMessage.SEVERITY_ERROR,
                   "Sorry, we encountered IRC services problems. Try again later.",
                   "Sorry, we encountered IRC services problems. Try again later."));
        return null;
       }
       return "chat";
   }
...
}

As you can see our bean extends the PirBot abstract class. So we just using PircBot api in order to get connected to server. And performing redirect to most interesting for us chat.xhtml page.

Client main page

Screenshot below shows you the result we want to achieve on that page:

Here is the complete listing of the chat.xhtml page. We'll review it in details below:

<script>
    function getMessageString(data){
        return data.author + " - " +data.timestamp+ ": " + data.text;
    }
</script>
<rich:panel header="Welcome to #{chatBean.channelName} channel at #{chatBean.serverName}" 
id="chatpanel">
    <rich:panel styleClass="chatOutput" bodyClass="#{chatBean.channelName}Output" />
    <rich:panel styleClass="chatList">
        <rich:list value="#{chatBean.users}" var="user" id="users" type="unordered">
            #{user.nick}
        </rich:list>
    </rich:panel>
    <br clear="all" />
    <hr />
    <h:form>
        <a4j:push address="#{chatBean.listSubtopic}@chat"
            onerror="alert(event.rf.data)">
            <a4j:ajax event="dataavailable" render="users" execute="@none" />
        </a4j:push>
        <a4j:push address="#{chatBean.messagesSubtopic}@chat"
            onerror="alert(event.rf.data)" ondataavailable="jQuery('&lt;div/&gt;').
            prependTo('.#{chatBean.channelName}Output').text(
            getMessageString(event.rf.data))" />
        <h:inputTextarea value="#{chatBean.message}" rows="3" style="width:80%" id="nm" />
        <a4j:commandButton value="Send" action="#{chatBean.send}" render="@none" execute="@form" />
    </h:form>
    <hr />
    <h:form>
        <rich:panel header="Change nickname:">
            <h:inputText valueChangeListener="#{chatBean.changeNick}" id="cn" />
            <a4j:commandButton value="Change" execute="@form" render="@none"/>
        </rich:panel>
        <h:commandButton value="Disconnect" action="#{chatBean.leave}"/>
    </h:form>
</rich:panel>

I will show you two options of performing push updates.

  1. Using ondataavailable JavaScript handler which will grab the data from the JMS event directly on the client.
  2. Using a4j:ajax behavior to trigger an Ajax request which will perform partial update when the push informs us about server event.

So the first panel:

<rich:panel styleClass="chatOutput" bodyClass="#{chatBean.channelName}Output" />

is just a container for the chat text which will be updated via JavaScript.

And the second panel:

<rich:panel styleClass="chatList">
    <rich:list value="#{chatBean.users}" var="user" id="users" type="unordered">
        #{user.nick}
    </rich:list>
</rich:panel>

contains the rich:list component which displays the users connected to the channel. It will be updated via an Ajax request that is triggered when the event about list change is populated at server side.

Client side updates on server-side events using JavaScript

Let's review the first a4j:push component more closely:

<a4j:push address="#{chatBean.messagesSubtopic}@chat" onerror="alert(event.rf.data)"
    ondataavailable="jQuery('&lt;div/&gt;').prependTo('.#{chatBean.channelName}Output').
    text(getMessageString(event.rf.data))" />

It's used to get the messages into the main chat window. Here is the TopicContext declaration and main methods from the ChatBean which are generates events for that push:

import org.richfaces.application.push.TopicKey;
import org.richfaces.application.push.TopicsContext;
...
private transient TopicsContext topicsContext;
public String getMessagesSubtopic() {
   return this.getUserName() + SUBTOPIC_SEPARATOR + channelName;
}
private TopicsContext getTopicsContext() {
if (topicsContext == null) {
topicsContext = TopicsContext.lookup();
}
return topicsContext;
}
@Override
protected void onMessage(String channel, String sender, String login, String hostname, String message) {
   try {
       Message messageObject = new Message(message, sender, DateFormat.getInstance().format(
new Date()));
       getTopicsContext().publish(new TopicKey("chat", getMessagesSubtopic()), messageObject);
   } catch (MessageException e) {
       LOGGER.error(e.getMessage(), e);
   }
}
public void send() {
   this.sendMessage(CHANNEL_PREFIX + channelName, message);
   try {
       Message messageObject = new Message(message, this.getName(), 
DateFormat.getInstance().format(new Date()));
       getTopicsContext().publish(new TopicKey("chat", getMessagesSubtopic()), messageObject);
   } catch (MessageException e) {
       LOGGER.error(e.getMessage(), e);
   }
}

onMessage method - just overriden PircBot method and it's invoked when the message comes from the other chat users. And send method is invoked when we are sending a message. This is a standard JSF action of the send button.

As you can see in order to raise an event for a4j:push we just publish it to the TopicContext. publish method accepts two parameters:

  • TopicKey key - adress which consist of topic and subtopic names.
  • Object data - actual data passed to client side event.

Messages subtopic generated by getMessagesSubtopic() method used by a4j:push component on the page and is unique for every user and channel, so only current user will receive the event populated by the object.

The Message object passed as data is pretty simple POJO with three String properties - author, text and timestamp. It's later used on the client in push oncomplete to create formatted string by getMessageString(data) JavaScript method and later add to chat div:

<script>
    function getMessageString(data){
        return data.author + " - " +data.timestamp+ ": " + data.text;
    }
</script>
IMPORTANT: As was mentioned before the other way to publish an event is by just sending it to JMS bus. So you have no need to use our TopicContext in this common case. We've just used this approach for simple example as we have no components other than our simple JSF bean. See Additional Details section for more information about publishing via JMS bus.

Ajax updates on server-side events using a4j:ajax

Now let's review the second approach to perform updates according to events received by a4j:push:

<a4j:push address="#{chatBean.listSubtopic}@chat" onerror="alert(event.rf.data)">
    <a4j:ajax event="dataavailable" render="users" execute="@none" />
</a4j:push>

It's used to update the rich:list which shows the current channel users. Here is the main methods from the ChatBean which are generates events for that push:

public String getListSubtopic() {
   return this.getUserName() + SUBTOPIC_SEPARATOR + channelName + "List";
}
@Override
protected void onUserList(String channel, User[] users) {
   try {
       getTopicsContext().publish(new TopicKey("chat", getListSubtopic()), null);
   } catch (MessageException e) {
       LOGGER.error(e.getMessage(), e);
   }
}
@Override
protected void onJoin(String channel, String sender, String login, String hostname) {
   try {
       getTopicsContext().publish(new TopicKey("chat", getListSubtopic()), null);
       Message messageObject = new Message("joined channel", sender, 
           DateFormat.getInstance().format(new Date()));
       getTopicsContext().publish(new TopicKey("chat", getMessagesSubtopic()), messageObject);
   } catch (MessageException e) {
       LOGGER.error(e.getMessage(), e);
   }
}

We are using the same publishing through TopicContext at server side just defining different subtopic for that a4j:push. And passing null as data because we do not planning to process anything at client side. That's where:

<a4j:ajax event="dataavailable" render="users" execute="@none" />

come in play. When push receives the event an ajax behavior sends a request which just perform rich:list render with new values. Pretty simple isn't it?

Additional Details

There I want to pay your attention to some details not covered within the article.

Single Connection

As you can see in this example we used two a4j:push component on a single page in order to demonstrate two different ways to process push events. It is important to know that this does not mean wo connections are getting opened. All the instances of the push component uses single connection and only the subscribed one gets the event for processing according to it's adress after some event is received. You can verify that by using Firebug for FireFox for example.

Publishing via JMS bus

JMS messages types supported by push are:

  • ObjectMessage
  • TextMessage

Corresponding data from getObject or getText passed to DataSerializer and getting serialized to the client data(to JavaScript using default serializer).

To be Continued...

And finally I want to announce topics which planned to be covered in next Push related articles.

Integration with CDI events

Being a first class citizen in JEE6 ecosystem CDI getting paid much attention during RichFaces development for sure. And support of CDI event system by a4j:push are also topic for upcoming separate blog entry!

And more...

There are a lot of possibilities with this component, too many to describe using just a single article. So follow our blogs or RichFaces twitter for any future examples and documentation updates related to this great component!


[Get updates of my blogs in twitter]

[My jroller.com blog]

RichFaces Showcase Online at Google App Engine!!

Posted by Jay Balunas    |       |    Tagged as JSF Rich Faces Seam

Now that RichFaces 4.0.0.Final is just a couple weeks away, we've had time to finalize our RichFaces Showcase and get it hosted up on Google App Engine (GAE)! Now you have a great way to explore all of the great RichFaces 4.0 components, and give them a try yourself (no login required). Plus we have all the instructions you need to get your own application running up on GAE. You can even host your own version of the RichFaces Showcase application!

Overview of the showcase

The showcase application is a gallery of RichFaces components that our project put together in order to demonstrate how to use the various tags available. This includes basic use cases, but also some more complex examples that have been asked about on our user forums. We've added enough information and source code to get you started quickly and you can access it anytime, so it is a great way to reference components.

The primary link to the hosted demo is http://richfaces.org/showcase, so go check it out today!

Quota's

Anyone familiar with Google App Engine will know about quota's. We've configured the application with additional quota allowances and we'll see how it handles under load. We've run it through its paces, but nothing tests like the real world :-) If for some reason it is not accessible, or you get unexpected errors please let us know over at our user forums.

What's next for the showcase

Once RichFaces 4.0.0.Final is released we have many plans for the showcase application. These include contextual linking to JavaDocs, components guide articles, etc…. We also want to add support for more devices such as phones, and tablets! We'll also be adding additional use-cases based on your feedback, and questions. The list could certainly keep going, but we would appreciate any ideas you have.

Hosting your own

As I said we have put together all of the information needed to get started with RichFaces 4 and JSF 2 on GAE. It can be found at our wiki page How to use RichFaces 4.0 with Google App Engine. In there you will find:

  • Updates required for any JSF 2 application on GAE
  • Information on RichFaces maven-resources-plugin to statically generate skinning resources
  • How to upload and deploy your application
  • Detailed steps and links to get your own version of the RichFaces Showcase running
  • Information on our RichFaces GAE archetype so you don't have to start from scratch on a new application

[Project Site] [Downloads] [JIRA] [User Forums] [Design Forums] [RichFaces Twitter]

RichFaces 4.0.0.CR1 is Here!!

Posted by Jay Balunas    |       |    Tagged as JSF Rich Faces Seam

RichFaces 4.0.0.CR1 is here!! You can get the 4.0 candidate release distribution at our project site's download page, or if you are using maven you can follow our: How to add RichFaces 4.X to Maven Based Project wiki page.

We are excited about this release as it looks like the only CR release that will be needed before we release 4.0.0.Final. We still need your feedback, to help run it through its paces. As I've said before CR can also stand for Community Required when you are talking about an open source projects. If you have any problems, or run into any issues with the release please let us know over on the User Forums.

If all goes according to plan look for the final release at the end of this month!! It has been a long haul, but the project team, and community have just been fantastic!! We are almost there and to give back to our community please remember to vote for the RichFaces contributors for the JBoss Recognition Awards!!

Updates in CR1

This has been a busy phase of stabilization, clean up, and fixing. We are obviously not adding new components in this phase, but we have piled on the polish. Many of the issues found were from the community and that is greatly appreciated! I've included a summary below of the major items addressed in CR1. As usual you can checkout all the details in the Jira Release Notes.

  • Greatly stabilized the Client Side Validation (CSV) feature, and message components.
  • MyFaces support was also improved, and switched to it for some of our demo applications
  • Our RichFaces Showcase demo got a new design and added new demos! Check out the readme.txt in the distribution for more.
  • Dependencies were updated to use latest versions: JQuery 1.5.1, MyFaces 2.0.4, Mojara 2.0.4, Atmosphere 0.6.4.
  • The Push component was polished. Look for a blog on this soon
  • Our RichFaces 3.X - 4.X migration guide has moved to the wiki for quicker updates, and with new information!
  • All of our components had work done on them, but specifically our switchable panels, and panels menus are much improved.
  • Our IDE support via our taglib files is also nearly complete!

Next Up 4.0.0.Final!!

We should be less than a month away from the release of RichFaces 4.0.0.Final!! We're working on minor clean up jira's and reviewing any issues you guys bring up, but CR1 is basically it.

It is more critical than ever that if you find an issue, have any comments or ideas please let us know through our forums, or our project jira. See our Project Calendar and the Meeting Information page for more details, agendas, and minutes.

[Project Site] [Downloads] [JIRA] [User Forums] [Design Forums] [RichFaces Twitter]

I have some exciting news! The RichFaces project is looking to hire some new JBoss Core Developers, and we want to hear from you. Right now we have two positions open, one is a Senior+ Software Engineer and the other is for a Software Engineer.

These positions offer an opportunity to work on one of the most popular JavaServer Faces (JSF) component libraries out there, and for one of the greatest companies to work for - Red Hat! These roles require advanced technical knowledge of both client, and server side technologies including Java, JavaScript, CSS, and HTML. Although a good attitude, motivation, and drive are also very important. We will be innovating and developing the future of enterprise web-tier technologies which will include cloud & mobile based platforms, HTML5, CSS3, and more!!

As a JBoss core developer you will be expected to be a community member/leader in our open source projects, and eventually a voice for RichFaces, and JBoss in general. If you have ever wanted to work on an open source project full time, and be part of a special group of developers this is your chance!!

[Project Site] [Downloads] [JIRA] [User Forums] [Dev Forums] [RichFaces Twitter]

back to top