The Art of Software Development

Jim Boone’s thoughts on software development and other important matters

Archive for the 'Flex' Category

RIA Prototype Client Using BlazeDS Messaging and JMS - J2EE Server

In a previous posting I gave an overview of the dashboard prototype that I created to investigate BlazeDS messaging with Flex clients. This posting focuses specifically on the J2EE application server component. I encourage you to read the prototype overview section of my initial post if you have not done so already to glean an understanding of what this server component does in the prototype.

Server Architecture

The EJB3 server architecture is quite basic and consists of one interface, one enterprise Java Bean (EJB), and one plain old Java object (POJO) value object. ITimer is a local interface that is implemented by the stateless DataGeneratorBean EJB. The DataGeneratorBean takes advantage of EJB timer service in order to generate events at the frequency specified by the client. You can start and stop message generation by calling the startTimer() or stopTimer() methods of the DataGeneratorBean EJB (these are the methods called by the client to start and stop message generation). It should be noted that by default EJB timers are persistent. That is if the timer is running when you shut the application server down it will start up automatically when you start the application server and again.

The MetricsVO value object is used to encapsulate the metrics data. A corresponding MetricsVO object is defined within the Flex client and the [RemoteClass(alias='info.jimboone.MetricsVO')] meta tag is added to the Flex definition object to assist BlazeDS in translating the Java object to/from the ActionScript object . You can view all of the Java EJB source files here.

BlazeDS Configuration

Integration of the J2EE server with BlazeDS occurs in the web.xml file. All that is required here is the definition of the MessageBrokerServlet servlet and a listener that keeps track of the HTTP Flex sessions (HttpFlexSession). This is fairly straightforward and very well documented within the BlazeDS Developers Guide (you can also view the web.xml files in the turnkey applications examples). The complete web.xml file is shown below:

Read more

3 comments

RIA Prototype Client Using BlazeDS Messaging and JMS - Flex Client

In a previous posting I gave an overview of the dashboard client that I created to investigate BlazeDS messaging with Flex clients. This posting focuses specifically on the Flex client.

One of the purposes of an application dashboard is to provide the user a means of rapidly discerning the state of an application using data visualization. I couldn’t think of a better use of Flex and than visualizing data! I am partial to real-time strip chart plots since you can monitor the history of operational parameters over a period of time. I am also partial to bar type meter that show the current value of a parameter and maybe even a high water mark. I envisioned a final dashboard application with many such strip charts and bar meters. The first objective of the prototype was to scope out an efficient way of displaying data for one set of metrics.

Charting Components

I wanted to try out some of the stock Flex charting components since I had never had the opportunity to work with them before. The LineChart component looked like a perfect component to use to draw my data in real time. Unfortunately, the LineChart does not allow you to present data in the same way that say the Windows performance monitor does as shown below.

Windows Performance Strip Chart

You basically have the choice of moving the whole chart as the performance monitor does or moving the data plot as you can with the bar chart component. Once I got over my preconceived notions of how a strip chart should work I found the LineChart to be perfectly adequate. The following show the LineChart component in the dashboard demo.

Dashboard Strip Chart

Although the stock LineChart component appears adequate for my purposes, I’m still a bit tempted to try to construct a strip chart component. After checking out the Degrafa web site, it looks like degrafa may be a good tool set to use in constructing a moving strip chart. I suppose I can also make my LineChart appear a bit more polished through CSS. Unfortunately, making UIs look pretty has not been in my job description up until this point so I have a bit to learn.
Read more

No comments

RIA Prototype client using BlazeDS messaging and JMS - Overview

Objectives

In this multi-part post, I will present a prototype that I developed that examines the integration of BlazeDS with a Java 2 Enterprise Edition (J2EE) messaging back-end. I have split the posting into three sections the first being an overview, the second presenting the Flex client and the third dealing with J2EE integration using EJB3. I recognize that many of you use other back-end server technologies such as Cold Fusion, PHP, or Ruby so you can ignore the third posting if you want to although the server Flex configuration files may be the same.

My objectives for writing the prototype were the following:

  • Configure BlazeDS messaging between a J2EE JMS topic and Flex clients
  • Examine the difference between BlazeDS polling and long-polling messaging
  • Tweak the various BlazeDS configuration parameters and observe the effects on the J2EE application server
  • Demonstrate Flex remoting with EJB3
  • Gain experience working with the Flex charting components for real-time charting application
  • Ensure that the client components utilize memory efficiently

Prototype Overview

I chose to develop a dashboard application that basically plots the value of three performance parameters in real time. This prototype mimics the functionality of an AIR application that I will be writing to monitor a production J2EE web application. The prototype application consists of a line chart that plots the performance parameters in real time and a bar chart that shows the instantaneous value for each parameter. The parameter values are generated randomly by the backend server code which places a value object containing these values into a JMS topic that the BlazeDS message broker is listening to. These messages will be forwarded to the Flex client when it is connected to the topic. The following diagram illustrates the basic configuration of the prototype.

Prototype Overview

The Flex client is used to start and/or stop a standard EJB timer session bean which creates a metrics data value object and sends it to a JMS topic (with topics messages are delivered to all subscribers) every time the timer fires. The user can set the frequency that the timer fires from the client. The EJB timer is controlled from the client via remote method calls. An EJB3 adaptor written by Ryan Norris was used to interface the Flex message broker with the J2EE application server. This link will take you to Ryan’s EJB and Flex Integration component.

The JMSAdapter class that is shipped BlazeDS is used to connect the message broker to the JMS topic and forwards messages to all Flex client subscribers. This adapter is feature rich and allows you to set about any configuration setting that a JMS client would need to. I even successfully tested connecting to a secured topic with no problems!

The following is a screenshot of the Flex client. It is not pretty, but it is an effective tool for exploring Flex and BlazeDS messaging. Click here for a full size image.

Dashboard Thumbnail

References

I would also like share many of the excellent references that I have found while developing this prototype. Of course the BlazeDS Developers Guide is a must read but it can be a bit overwhelming if you just want to get a sense of the big picture. I found the article entitled Introduction to the Flex Message Service to be an excellent introduction into Flex messaging. It is perhaps my personal favorite. You might also want to check it out an article titled Getting started with BlazeDS which provides a gentle introduction into BlazeDS messaging. Finally, there is an article on the Flex Developers Journal website titled How to Create a Multi User Flex Application Using JMS. Be warned that your browser will be spammed with all sorts of advertisements, a pet peeve of mine, but I suppose the Flex Developers Journal needs to pay the bills somehow. Stay tuned for some code!

No comments

More Thoughts About BlazeDS

In my first posting concerning BlazeDS, I described the effort it took for me to convert from remoting with GraniteDS to remoting with BlazeDS. I have been expanding my knowledge of BlazeDS by studying messaging and plan to write a posting that extends the examples given in the turnkey distribution to include an honest-to-goodness JMS example. But first I would like to share what I have learned since my initial BlazeDS posting.

The BlazeDS product suite is extremely well documented. Adobe has written a BlazeDS Developers Guide that is over 170 pages long and it is chocked full of good information (they also include a turnkey download distribution that demonstrates the various forms of remoting and messaging). Now like all good developers I’m sure you all read the documentation from beginning to end before you ever dive into code. Right. I like to get the big picture first then start working with the product so that I can wrap my brain around the concepts a bit easier. I will then go back in fill in the details by reading the documentation again. So as a practical introduction to BlazeDS, I converted an existing application from GraniteDS to BlazeDS.

Read more

No comments

Converting from GraniteDS to BlazeDS Remoting

In this posting I will summarize the steps that I took and issues encountered while converting the remoting infrastructure of a production Flex 3 application from GraniteDS to Adobe’s BlazeDS. Christophe Coenraets from Adobe has written an excellent article titled Using BlazeDS with Spring that provides an introduction to using BlazeDS with the Java-based Spring framework. I recommend reading that article as a gentle introduction to the subject. This posting focuses on applying BlazeDS to a project that is currently using GraniteDS.

Binary Remoting Versus Web Services

During the Flex 360 Conference in Atlanta, I learned that Adobe open-sourced the remoting and messaging components of their LifeCycle Data Services (LDS) offering. This was good news! Several months ago when we started down the Flex RIA path we knew we needed a good remoting framework. We considered LDS but the cost was off-scale high for our project (we could barely convince management to by five licenses for Flex Builder)! This gave us no choice but to use SOA or find another binary remoting solution. That is when I discovered the GraniteDS open source project and found a true gem.

I am partial to binary remoting because of the better wire transfer efficiency relative to XML-based protocols…squish those bits and get an approximate order of magnitude efficiency gain. However, the biggest reason I prefer binary remoting is that I get object conversions for free! This is true for both GraniteDS and BlazeDS. Both products will automatically convert data objects between your Java application on the back-end and ActionScript 3 (AS3) on the front end. The only price you must pay is:

  • You must define an ActionScript class with instance variables that correspond the bean pattern name on the corresponding Java object
  • You must add a simple meta tag on the corresponding ActionScript class to allow the backend to connect the wires [RemoteClass(alias="<full path of corresponding Java class name>”)]

Although the new ECMAScript for XML functionality built into ActionScript3 is the BEST XML parsing I have ever used, I want to always use objects in my front end. That means I need to marshal the XML data structure to and from my AS3 objects on the client. That is just grunt work. Code generators like those included in Axis 2 will do that dirty work for you in the Java world, but to my knowledge it doesn’t exist yet in Flex Builder 3.

Downloading BlazeDS and Extracting the Jars

You can download both release builds and nightly builds of the BlazeDS code from the Adobe open source web site. I downloaded the latest release build (3.0.0.544). The release download comes in three flavors: Turnkey, Binary and Source Distribution. I recommend the Turnkey which includes a Tomcat web server, Flex 3 SDK and several sample applications. That is more than enough unless you want to look through the code in which case simply download the source while you are there or browse the Subversion repository.

Unzip the Turnkey distribution, start up the hypersonic database per the instructions, fire up Tomcat and work your way through all of the examples. There are some really good examples here!

Integrating with Your Application

Once I had played with the sample applications it was time to figure out how to integrate BlazeDS into my existing application. Conspicuously absent from the download was a distribution directory that contained the required jars. What? The BlazeDS distribution contains five base jars but you’re going to have to dig into the exploded war file lib directory to find them. In my opinion, this is simply bad form and others agree. I was about to open an enhancement request on this issue but I was beat to it.

You might also want to also observe the other presumably dependent jars that are included in the lib directory. This brings me to my second issue. What Java libraries does BlazeDS depend on and what versions? In the Java world I use Maven to track dependencies and I think this would be a good enhancement for the BlazeDS project as well. Once again I was not the first to make this observation.

Once you place the necessary BlazeDS jars into the WEB-INF/lib directory of your project (or declare the dependencies in your Maven pom.xml file) you are ready to configure BlazeDS. Both GraniteDS and BlazeDS utilize a messaging servlet and message filter to intercept the HTTP stream and process the remoting call, as necessary. This configuration is made in the web.xml file. The following shows the configuration necessary to plumb BlazeDS in the web.xml file.

...
    <!-- Http Flex Session attribute and binding listener support -->
<listener>
<listener-class>flex.messaging.HttpFlexSession</listener-class>
    </listener>
    <!-- MessageBroker Servlet -->
    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <display-name>MessageBrokerServlet</display-name>
        <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
<param-name>services.configuration.file</param-name>
<param-value>/WEB-INF/flex/services-config.xml</param-value>
       </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
		<url-pattern>/apps/messagebroker/*</url-pattern>
    </servlet-mapping>
...

Easy enough. Now that our BlazeDS MessagBrokerServlet and the HttpFlexSession filter have been configured, it is time to move on to the Flex services-config.xml file. There were several changes that needed to be made in this file. The complete services-config.xml file for my application is listed below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
<services-config>
  <services>
    <service id="remoting-service">
		    class="flex.messaging.services.RemotingService"
                    messageTypes="flex.messaging.messages.RemotingMessage" /&gt;
   <adapters>
        <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"></adapter-definition>
      </adapters>
 
      <destination id="EpUtilService">
        <channels>
          <channel ref="blazeds-amf"></channel>
<properties>
            <factory>springFactory</factory>
            <source>EpUtilServiceFacadeGranite</source>
          </properties>
        </channels>
      </destination>
    </service>
    <factories>
      <factory id="springFactory">
            class="com.bofa.esm.utility.flex.SpringFactory" /&gt;
      <channels>
        <channel-definition id="blazeds-amf" class="mx.messaging.channels.AMFChannel">
          <endpoint uri="http://{server.name}:{server.port}/{context.root}/apps/messagebroker/" class="flex.messaging.endpoints.AMFEndpoint">
          </endpoint>
        </channel-definition>
      </channels>
    </factory>
  </factories>
</services></services-config>

One difference between the GraniteDS and BlazeDS configurations is the required adapter configuration shown in line 6. GraniteDS doesn’t include this configuration item. I didn’t research it, but I suspect the adapter definition is necessary because BlazeDS can convert to multiple object types (perhaps messages?) while GraniteDS is focused on Java only.

The next configuration change was the definition of the Spring factory shown in line 23. Out of the box GraniteDS as a built-in Spring factory so BlazeDS must as well, right? Wrong! Much to my surprise BlazeDS does not! As a result you the developer are responsible for writing the glue code between BlazeDS and the Spring application context. It’s not really hard and that nut has already been cracked. I found several examples of a SpringFactory object that can be used with BlazeDS. Upon further investigation it all tracked back to code written by Jeff Vroom that was included in the Using BlazeDS with Spring article. The SpringFactory class is shown below with comments removed.

package com.bofa.esm.utility.flex;
 
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
import flex.messaging.FactoryInstance;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;
 
/**
 * This class is implemented by factory components which provide
 * instances to the flex messaging framework.  To configure flex data services
 * to use this factory, add the following lines to your services-config.xml
 * file (located in the WEB-INF/flex directory of your web application).
 *
 
 *<code>
 *	&lt;factories&gt;
 *     &lt;factory id="spring" class="com.bofa.esm.utility.SpringFactory" /&gt;
 *  &lt;/factories&gt;
 *</code>
 *
 * @author Jeff Vroom
 */
public class SpringFactory implements FlexFactory
{
    private static final String SOURCE = "source";
 
    /**
     * This method can be used to initialize the factory itself.  It is called with configuration
     * parameters from the factory tag which defines the id of the factory.
     */
    public void initialize(String id, ConfigMap configMap) {}
 
    /**
     * This method is called when we initialize the definition of an instance
     * which will be looked up by this factory.  It should validate that
     * the properties supplied are valid to define an instance.
     * Any valid properties used for this configuration must be accessed to
     * avoid warnings about unused configuration elements.  If your factory
     * is only used for application scoped components, this method can simply
     * return a factory instance which delegates the creation of the component
     * to the FactoryInstance's lookup method.
     */
    public FactoryInstance createFactoryInstance(String id, ConfigMap properties)
    {
        SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);
        instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
        return instance;
    } // end method createFactoryInstance()
 
    /**
     * Returns the instance specified by the source
     * and properties arguments.  For the factory, this may mean
     * constructing a new instance, optionally registering it in some other
     * name space such as the session or JNDI, and then returning it
     * or it may mean creating a new instance and returning it.
     * This method is called for each request to operate on the
     * given item by the system so it should be relatively efficient.
     *
 
     * If your factory does not support the scope property, it
     * report an error if scope is supplied in the properties
     * for this instance.
     */
    public Object lookup(FactoryInstance inst)
    {
        SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
        return factoryInstance.lookup();
    } 
 
    static class SpringFactoryInstance extends FactoryInstance
    {
        SpringFactoryInstance(SpringFactory factory, String id, ConfigMap properties)
        {
            super(factory, id, properties);
        }
 
        public String toString()
        {
            return "SpringFactory instance for id=" + getId() + " source=" + getSource() + " scope=" + getScope();
        }
 
        public Object lookup()
        {
            ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(flex.messaging.FlexContext.getServletConfig().getServletContext());
            String beanName = getSource();
 
            try
            {
                return appContext.getBean(beanName);
            }
            catch (NoSuchBeanDefinitionException nexc)
            {
                ServiceException e = new ServiceException();
                String msg = "Spring service named '" + beanName + "' does not exist.";
                e.setMessage(msg);
                e.setRootCause(nexc);
                e.setDetails(msg);
                e.setCode("Server.Processing");
                throw e;
            }
            catch (BeansException bexc)
            {
                ServiceException e = new ServiceException();
                String msg = "Unable to create Spring service named '" + beanName + "' ";
                e.setMessage(msg);
                e.setRootCause(bexc);
                e.setDetails(msg);
                e.setCode("Server.Processing");
                throw e;
            }
        }
    }
}

So that lead me to think about bringing yet another enhancement request. Why can’t this class be included in the BlazeDS project that way we can all quit reinventing the wheel? Once again I was beaten to the punch. It might also be beneficial to include factories for both EJB3 and JBoss Seam. I might write for myself the next time I’m working on a project utilizing those technologies.

Now with my web.xml file and services-config.xml file complete, my project would successfully deploy to JBoss, but when the Flex app made a back-end call I got an ugly IllegalStateException with no other information. Fortunately I had the BlazeDS source code and I could see where things were blowing up. It looked like something related to an invalid endpoint definition. Sure enough once I corrected the end point definition in the services-config.xml file the Flex app fired on all cylinders! Thus far our Flex app has behaved as normal unaware that it is being serviced by BlazeDS. Thank you Adobe!

Summary

By swapping out the messaging servlet, a session listener, and creating a new SpringFactory class I was able to seamlessly change my remoting infrastructure from GraniteDS to BlazeDS. The whole exercise wasn’t as simple as I hoped, but it wasn’t that painful either. The following is a summary of the major issues in issues to during his conversion:

  1. You cannot download a zip file with just the BlazeDS distribution jars. You must extract them from the war files. A better solution would be to publish BlazeDS in a public Maven 2 repository such as http://repo1.maven.org/maven2 or some other public site
  2. The BlazeDS dependencies are not clear. This is a corollary to above. It would not be an issue if Maven 2 dependency poms were specified
  3. There are no factories for integrating with other open source projects like Spring, EJB3, or JBoss Seam. Must currently role your own integration which isn’t really hard but that’s the point

Other resources

I did find a few other good resources that you might find useful:

1 comment

Next Page »