Flex with JMS using BlazeDS, Jetty and ActiveMQ

I recently had to develop a small web-based client that exposed results from a JMS Topic to a user. I’ve used Flex in the past and liked it so I thought I’d develop the client in Flex instead of using a standard Java Webapp.

A Flex client cannot talk to a JMS topic or queue directly – typically you would not want it to anyway since firewalls would block the ports that JMS runs on. Instead, you use something called BlazeDS to do expose the JMS queue/topic to the flex client. Blaze talks to the Flex client over HTTP so there is no problems with firewalls. Blaze does other things but in this post I’m just going to talk about messaging.

In this post I’ll describe the flex application that I constructed. It uses ActiveMQ as the JMS provider, runs a Java webapp in Jetty that contains the Blaze Jars and configuration and has a Flex application that talks to Blaze. The flex application is basically the same as the Trader Desktop sample application that comes with Blaze but with a few customizations.

You can download the full source of the examples here.

I should note that this post was very helpful in getting me up and running.

ActiveMQ

The example uses ActiveMQ (which is a JMS broker) running standalone. You don’t really need to understand ActiveMQ for this example project. Simply download it from here and unzip the ZIP file to somewhere on your machine. Then, run it from that directory. On my (Windows) machine, I have it installed in

C:\installed_apps\activemq\apache-activemq-5.2.0

so to run it I do:

C:\installed_apps\activemq\apache-activemq-5.2.0\bin\activemq.bat

Once you have started up ActiveMQ just leave it running for the duration of this example.

Maven Configuration

The application is build with Maven. Adobe publish the BlazeDS jars in the public Maven repository it is just a case of adding them to dependencies section in the POM. Download the source to see the example.

Configuring the Jetty JNDI resources

The web application which contains the Blaze functionality will run in Jetty so we need to configure Jetty JNDI. You will find this file in /server/src/main/resources/jetty-env.xml. Below is the configuration for the ActiveMQ connection factory and the single JMS stockQuoteTopic to which we will publish information to and read information from:

    <!-- ActiveMQ Connection Factory -->
    <new id="myBroker" class="org.mortbay.jetty.plus.naming.Resource">
        <arg>
            <ref id="wac" />
        </arg>
        <arg>jms/flex/ActiveMqConnectionFactory</arg>
        <arg>
            <new class="org.apache.activemq.ActiveMQConnectionFactory">
                <arg>tcp://localhost:61616</arg>
            </new>
        </arg>
    </new>
 
    <!-- ActiveMQ stock quote Topic-->
    <new id="stockQuoteTopic" class="org.mortbay.jetty.plus.naming.Resource">
      <arg><ref id="wac"/></arg>
      <arg>jms/stockQuoteTopic</arg>
      <arg>
        <new class="org.apache.activemq.command.ActiveMQTopic">
           <arg>stockQuoteTopic</arg>
        </new>
      </arg>
    </new>

Web.xml configuration

We have to do two important things in the web.xml; configure the Blaze servlet that permits the communication with the flex client and declare the JMS Connection Factory and Topic that we use in the application. Below is the Blaze servlet declaration:

    <!-- 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>/messagebroker/*</url-pattern>
    </servlet-mapping>

and below are the resource declarations:

 
    <resource-ref>
        <description>Connection Factory</description>
        <res-ref-name>jms/flex/ActiveMqConnectionFactory</res-ref-name>
        <res-type>javax.jms.QueueConnectionFactory</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
 
    <resource-env-ref>
        <resource-env-ref-name>jms/stockQuoteTopic</resource-env-ref-name>
        <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
    </resource-env-ref>

Note that the names “jms/flex/ActiveMqConnectionFactory” and “jms/stockQuoteTopic” correspond exactly with what was declared in the jetty-env.xml file.

Blaze configuration

Phew! Ok, we’ve configured Jetty and the web.xml. Now we just have to configure Blaze. The configuration files are in /server/src/main/webapp/WEB-INF/flex.

messaging-config.xml

This file contains the information on the JMS topics that we will connect to. Unfortunately some of this information is a duplicate of what was specified already in the web.xml and jetty-env.xml but that’s just how it is. I don’t want to get into explaining this file in details but the main thing to note is that we specify “java:comp/env/jms/flex/ActiveMqConnectionFactory” for the Connection Factory which corresponds to what we already configured in the jetty-env.xml and web.xml files. The only difference is that it has the java:comp/env bit at the start. The same goes for the destination-jndi-name element.

<service id="message-service" class="flex.messaging.services.MessageService">
    <adapters>
        <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
        <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/>
    </adapters>
 
    <!-- active MQ stock feed -->
    <destination id="market-data-feed">
        <properties>
            <jms>
                <destination-type>Topic</destination-type>
                <message-type>javax.jms.TextMessage</message-type>
                <connection-factory>java:comp/env/jms/flex/ActiveMqConnectionFactory</connection-factory>
                <destination-jndi-name>java:comp/env/jms/stockQuoteTopic</destination-jndi-name>
                <delivery-mode>NON_PERSISTENT</delivery-mode>
                <message-priority>DEFAULT_PRIORITY</message-priority>
                <acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
                <initial-context-environment>
                    <property>
                        <name>Context.INITIAL_CONTEXT_FACTORY</name>
                        <value>org.apache.activemq.jndi.ActiveMQInitialContextFactory</value>
                    </property>
                    <property>
                        <name>Context.PROVIDER_URL</name>
                        <value>tcp://localhost:61616</value>
                    </property>
                </initial-context-environment>
            </jms>
        </properties>
        <channels>
			<channel ref="my-polling-amf"/>
			<channel ref="my-streaming-amf"/>
        </channels>
        <adapter ref="jms"/>
    </destination>
 
</service>

services-config.xml

This file specifies the channels that can be used for communication between the flex client and the web application running blaze. For a full description of each channel type, see the blaze documentation. These channels are referenced in the messaging-config.xml file.

<services-config>
    <services>
        <service-include file-path="messaging-config.xml" />
    </services>
    <security/>
    <channels>
 
        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
 
 
        <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
        </channel-definition>
 
        <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
            <properties>
                <polling-enabled>true</polling-enabled>
                <polling-interval-seconds>4</polling-interval-seconds>
            </properties>
        </channel-definition>
 
 
    </channels>
    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Debug">
            <properties>
                <prefix>[BlazeDS] </prefix>
                <includeDate>false</includeDate>
                <includeTime>false</includeTime>
                <includeLevel>false</includeLevel>
                <includeCategory>false</includeCategory>
            </properties>
            <filters>
                <pattern>Endpoint.*</pattern>
                <pattern>Service.*</pattern>
                <pattern>Configuration</pattern>
            </filters>
        </target>
    </logging>
</services-config>

The flex client

Finally, we come to the flex client. This is a very slightly modified version of the trader desktop application that comes with the BlazeDS samples. The full source code of the traderdesktop.mxml file is located in /client/src directory of the download but it is quite long so I’m not going to publish it in the post. Instead I’ll highlight important parts as I go along.

If you have Flex Builder installed and want to view the source code using that, do the following:

  1. I’ll assume that you’ve downloaded the sample code to $SAMPLE_HOME
  2. In FlexBuilder, go to File > Import > Flex Project
  3. Select the ‘Project Folder’ radio button and use the browse button to select the folder $SAMPLE_HOME/trader-app/client.
  4. Click ‘finish’.
  5. Right-click on the newly imported project’s root folder and select ‘properties’.
  6. Select Flex Server from the tree on the left of the new dialog
  7. Click on the browse button next to the root folder input field and navigate to the folder $SAMPLE_HOME/trader-app/server/src/main/webapp
  8. Click on the validate location button and click ok.
  9. Getting a Java object out of the JMS topic

    JMS messages can contain a variety of payloads. In this post, I’ll demonstrate how you can use a Flex client to read serialized java classes and XML from JMS messages. We’ll look at Java classes first.

    NOTE: The following assumes that the ActiveMQ server is running. I explained how to do that earlier in this article.

    Let’s start up the Java Web application. Open a console and go to the $SAMPLE_ROOT/trader-app/server folder. Then run:

    mvn jetty:run

    Now, lets start up a Java class that puts some messages about stocks and shares into JMS. Open another console window (separate to the one now running Jetty) and go to $SAMPLE_ROOT/trader-app/server. Run the following:

    mvn exec:java -Dexec.mainClass="com.theserverlabs.flex.trader.JavaFeed"

    If you look at the source code of this class, what it does is create lots of JMS messages for different stocks and puts them in the “stockQuoteTopic” JMS topic. The Stock class looks like this:

    public class Stock implements Serializable {
    	protected String symbol;
    	protected String name;
    	protected double low;
    	protected double high;
    	protected double open;
    	protected double last;
    	protected double change;
    	protected Date date;
    	...
    }

    Now, in a web browser, go to http://localhost:9080. You should see the Flex trader application start up and after a short delay, it should start filling up with information about stock quotes. You should see lots of debug information in the console that is running the java web app.

    How does this work? Well, in the flex client, the subscribe() method is called for each stock. This configures a Consumer object that points to the JMS topic that publishes the stock quotes. The code is below:

    private function subscribe(symbol:String):void
    {
    	var consumer:Consumer = new Consumer();
    	consumer.destination = "market-data-feed";
    	consumer.channelSet = new ChannelSet([channels.selectedItem]);
    	consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);
    	consumer.subscribe();
    	consumers[symbol] = consumer;
    }

    The important thing here is that the consumer.destination is set to “market-data-feed” which corresponds to the destination that we configured in the blaze messaging-configuration.xml file. Each time we receive a message in this topic, we call the messageHandler() method:

    private function messageHandler(event:MessageEvent):void 
    {
    	var changedStock:Stock = event.message.body as Stock;
    	var stock:Stock = stockMap[changedStock.symbol];
     
    	BackgroundColorRenderer.symbol = changedStock.symbol;
     
    	if (stock)
    	{
    		stock.open = changedStock.open;
    		stock.change = changedStock.change;
    		stock.last = changedStock.last;
    		stock.high = changedStock.high;
    		stock.low = changedStock.low;
    		stock.date = changedStock.date;
    	} 
    }

    The cool part of this method is the first line. It takes even.message.body which is a serialized Java object (Stock.java) and converts it to a Flex Stock object – Stock.as. How does it do this? Well, there is a RemoteClass declaration in the Stock.as file that declares that this object maps to a remote object flex.samples.marketdata.Stock. Since the attributes of both classes are mappable, Flex can do the mapping. How cool is that?

    package samples.portfolio
    {
    	[RemoteClass(alias="flex.samples.marketdata.Stock")]
    	[Bindable]
    	public class Stock
    	{
    		public var symbol:String;
    		public var name:String;
    		public var low:Number;
    		public var high:Number;
    		public var open:Number;
    		public var last:Number;
    		public var change:Number = 0;
    		public var date:Date;
    	}	
    }

    Retrieving XML content from JMS messages in a flex client

    Although it’s nice to be able to retrieve Java classes from the JMS message body, it is quite common to construct JMS mesages that contain an XML body. This section shows you how to do it. The XML that we send in the JMS messages looks like this:

    <stock>
    	<symbol>BA</symbol>
    	<name>Boeing Company</name>
    	<low>83.0956875949062</low>
    	<high>83.45</high>
    	<open>83.45</open>
    	<last>83.0956875949062</last>
    	<change>83.0956875949062</change>
    </stock>

    Firstly, hit ctrl-c in the console windows running the web application and the JavaFeed class. Now, in Flex Builder, change line 83 of traderdesktop.mxml from:

    consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);

    to

    consumer.addEventListener(MessageEvent.MESSAGE, xmlMessageHandler);

    The xmlMessageHandler method is given below. Instead of ‘casting’ the message body to a Java object, it constructs a new Flex XML object using the content of the message body. Once this has been done, in Flex, you can refer to elements of the XML using the dot syntax. In this example, we refer to the ‘symbol’ sub-element of the stock XML as stockXml.symbol.

    private function xmlMessageHandler(event:MessageEvent):void 
    {
    	var stockXml:XML = new XML(event.message.body);
    	var stock:Stock = stockMap[stockXml.symbol];
     
    	BackgroundColorRenderer.symbol = stockXml.symbol;
     
    	if (stock)
    	{
    		stock.open = stockXml.open;
    		stock.change = stockXml.change; 
    		stock.last = stockXml.last;
    		stock.high = stockXml.high;
    		stock.low = stockXml.low;
    	}
    }

    To see the example working, start the jetty server again:

    mvn jetty:run

    and start up the XML feed (note that the class is different from the JavaFeed):

    mvn exec:java -Dexec.mainClass="com.theserverlabs.flex.trader.XmlFeed"

    hit refresh in the browser window that is running the Flex client. The client should work as it did in the previous example.

    Conclusion

    Although there is quite a lot of configuration on the web app side, hopefully this post has demonstrated how easy it is to integrate Flex with JMS using BlazeDS.

48 Comments on “Flex with JMS using BlazeDS, Jetty and ActiveMQ”

  1. #1 mike nimer
    on Jan 23rd, 2009 at 7:25 pm

    You should check out flexServerLib on google code. there is a Spring JMS adapter in that project. You can get rid of a lot of the configuration above and let Spring handle it. This adapter will then go through Spring to do the JMS work.

    hth,
    —mike

  2. #2 cease
    on Jan 23rd, 2009 at 8:54 pm

    Hi
    Whats the benefits of using messaging vs remote objects thanks

  3. #3 Guy Mac
    on Jan 23rd, 2009 at 9:05 pm

    Very cool, thanks for posting and including all the wiring details.

  4. #4 Kevin McCormack
    on Jan 26th, 2009 at 10:20 am

    @mike, thanks for pointing out that project. I’m not clear on which parts of the configuration you’d be able to remove with flexServerLib though – does BlazeDS still need messaging-config.xml and services-config.xml? I’ll definitely look into the project though.

    @cease, messaging is useful when you only want to notify a receiver when some data changes – in this case, when a stock price changes. If you were to implement this with remote objects, you’d have to write code that continually polled the server in case there was a change in the stock price.

    That perhaps isn’t too clear in this example because the Feed classes are regularly creating new messages and putting them in the topic. Imagine the situation where a stock price didn’t change all day. If you implemented stock price checking by remote objects, you’d have to poll every x seconds to check if the stock price changes whereas with messaging, the flex client can just wait for the server to notify it if there was a change.

    @Guy, thanks!

  5. #5 Arun
    on Jan 28th, 2009 at 7:11 pm

    Hi,

    I am getting this error trace when running through jetty maven plugin.
    Any Idea?
    Thanks

    Configuration problem at Connection

    Factoryjms/flex/ActiveMqConnectionFactoryjavax.jms.QueueConnectionFactoryContainer
    javax.naming.NameNotFoundException: No resource to bind matching name=jms/flex/ActiveMqConnectionFactory
    at org.mortbay.jetty.plus.naming.NamingEntry.bindToENC(NamingEntry.java:127)
    at org.mortbay.jetty.plus.webapp.Configuration.bindResourceRef(Configuration.java:73)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initResourceRef(AbstractConfiguration.java:262)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initWebXmlElement(AbstractConfiguration.java:161)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initialize(WebXmlConfiguration.java:289)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initialize(AbstractConfiguration.java:133)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configure(WebXmlConfiguration.java:222)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configure(AbstractConfiguration.java:113)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configureWebApp(WebXmlConfiguration.java:180)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configureWebApp(AbstractConfiguration.java:96)
    at org.mortbay.jetty.plus.webapp.Configuration.configureWebApp(Configuration.java:124)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1215)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
    at org.mortbay.jetty.Server.doStart(Server.java:217)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:345)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:286)
    at org.mortbay.jetty.plugin.Jetty6RunWarExploded.execute(Jetty6RunWarExploded.java:163)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:643)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:359)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:260)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:146)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:304)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:124)
    at org.apache.maven.embedder.MavenEmbedder.execute(MavenEmbedder.java:906)
    at org.maven.ide.eclipse.embedder.Maven2Executor.main(Maven2Executor.java:82)
    2009-01-28 18:35:51.209::WARN: Failed startup of context

    org.mortbay.jetty.webapp.WebAppContext@17dff15{/hospaa,F:\krisna\Hospa\hospaa3\hospaa-web\target\hospaa}
    javax.servlet.UnavailableException: Configuration problem
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initialize(WebXmlConfiguration.java:298)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initialize(AbstractConfiguration.java:133)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configure(WebXmlConfiguration.java:222)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configure(AbstractConfiguration.java:113)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configureWebApp(WebXmlConfiguration.java:180)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configureWebApp(AbstractConfiguration.java:96)
    at org.mortbay.jetty.plus.webapp.Configuration.configureWebApp(Configuration.java:124)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1215)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
    at org.mortbay.jetty.Server.doStart(Server.java:217)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:345)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:286)
    at org.mortbay.jetty.plugin.Jetty6RunWarExploded.execute(Jetty6RunWarExploded.java:163)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:643)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:359)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:260)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:146)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:304)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:124)
    at org.apache.maven.embedder.MavenEmbedder.execute(MavenEmbedder.java:906)
    at org.maven.ide.eclipse.embedder.Maven2Executor.main(Maven2Executor.java:82)

  6. #6 Kevin McCormack
    on Jan 30th, 2009 at 12:18 pm

    Hi Arun,

    It looks like your Jetty JNDI configuration in /server/src/main/resources/jetty-env.xml is not quite right.

    Have you got ActiveMQ running on your machine?

  7. #7 Arun
    on Jan 31st, 2009 at 3:23 pm

    Hi Kevin,

    Yes i am running the ActiveMQ server in my machine.
    This is my config file

    jms/flex/ActiveMqConnectionFactory

    tcp://localhost:61616

    jms/waitingPatientTopic

    waitingPatientTopic

    Any Problem with this?

  8. #8 Arun
    on Jan 31st, 2009 at 3:26 pm

    jms/flex/ActiveMqConnectionFactory

    tcp://localhost:61616

    jms/waitingPatientTopic

    waitingPatientTopic

    jms/flex/ActiveMqConnectionFactory

    tcp://localhost:61616

    jms/waitingPatientTopic

    waitingPatientTopic

  9. #9 Kevin McCormack
    on Feb 2nd, 2009 at 9:35 am

    Hi Arun,

    It is difficult to diagnose the problem that you are seeing since I can see from the configuration that you have posted that you are not running the exact code that I provided.

    It seems that the error you are getting occurs when Jetty processes the web.xml file. In that there is a connection factory – “jms/flex/ActiveMqConnectionFactory” configured but Jetty doesn’t know anything about it. This is usually because the jetty-env.xml file doesn’t correspond with the web.xml.

    I’d suggest that you check the web.xml and jetty-env.xml files to make sure that the names of the connection factory and topics correspond.

    If that doesn’t work, I’d recommend you download the example and run it without changing the code or configuration. Then once you know it works, change the example one small piece at a time (so that if something breaks, you know which change caused it) until it becomes what you want it to be.

    Sorry I can’t be more helpful.

  10. #10 Wits
    on Feb 18th, 2009 at 4:41 pm

    Hi,

    Thanks for this great example.

    I did run the application and everything seemed to go well. But how can I change the prices? I mean the figures are all 0.00. I just don’t understand really. I was expecting to see real time data being displayed and all that but nothing close. I could see loads of stuff on console but can’t figure out what they do

    If I add a symbol, where does it reflect within the application that I have actually done so. Can you please elaborate more?

    Thank you in anticipation

    Wits

  11. #11 Kevin McCormack
    on Feb 20th, 2009 at 10:24 am

    Hi Wits,

    If you take a look in /server/src/main/resources/portfolio.xml, you will find a list of stocks for which prices are published. What happens is the JavaFeed or XmlFeed class reads the list of stock quotes from this file and randomly generates a new price for the stock. It then puts a message in the JMS queue with the new price for the stock which is published to the Flex client using BlazeDS.

    Therefore if you add a symbol, it must be one of the ones declared in the portfolio.xml file.

    The prices should have changed automatically for you every few seconds. Are you sure you ran the JavaFeed or XmlFeed class (as appropriate)?

    It might be best to just start over again and see if that resolves your problem. Otherwise, look for some errors on the console and post them here so I can help some more.

    Hope this helps,

    Kevin.

  12. #12 Wits
    on Feb 20th, 2009 at 5:54 pm

    Thanks Kevin,

    That was quite helpful, well, to an extent. So the “add symbol” is actually meant to update the portfolio.xml; I couldn’t see anything that does that in the code anyway.

    I’m not generating any error at the moment. The code runs fine but, it’s just that when I ran “localhost:9080″, the display page was actually static.
    I thought there is a way one can actually change the price of a stock on the server and have an immediate price change reflection on the client (the display page), that is, updates the stock display price in the browser window.

    Sorry, am I making any sense? I’m kind of new to this whole stuff. But I read that BlazeDS facilitates or supports real-time update….

    What do you say please?

    Thanks

    Wits

  13. #13 Kevin McCormack
    on Feb 23rd, 2009 at 3:43 pm

    Hi Wits,

    No, “add symbol” does not update portfolio.xml. What I meant was that when you specify a symbol in “add symbol”, you can’t just specify any value – it must be a symbol that is declared in portfolio.xml.

    Are you saying that when you go to localhost:9080, none of the stock prices change?

    The prices should change when you run the JavaFeed or XmlFeed class (depending if you have configured the flex app to expect Java or XML data). These classes are creating a ‘price changed’ message on the server. This message should cause the price to change in the Flex app running in the browser.

    Hope this helps,

    Kevin.

  14. #14 Krishna
    on Feb 24th, 2009 at 8:08 am

    Hai while i try to connect with server from client this error is occured
    can u give any solution for this

    [BlazeDS]02/24/2009 [ERROR] [Message.General] Unhandled error when processing a message: java.lang.RuntimeException: MessageClient has been invalidated.
    incomingMessage: Flex Message (flex.messaging.messages.CommandMessage)
    operation = subscribe
    selector = null
    clientId = 46E57868-F51B-8446-DE4F-D68259449C2B
    correlationId =
    destination = waitingPatientFeed
    messageId = F7B985DF-9F3B-816F-1299-A713089670D7
    timestamp = 1235458656453
    timeToLive = 0
    body = {}
    hdr(DSEndpoint) = my-streaming-amf
    hdr(DSId) = 46DCCEF6-F10F-1225-6B67-D56A2E84890C
    hdr(DSValidateEndpoint) = true
    errorReply: Flex Message (flex.messaging.messages.ErrorMessage)
    clientId = 46E57868-F51B-8446-DE4F-D68259449C2B
    correlationId = F7B985DF-9F3B-816F-1299-A713089670D7
    destination = waitingPatientFeed
    messageId = 46E584EC-150C-2D4D-4D5C-CFEBE3D47BA4
    timestamp = 1235458657765
    timeToLive = 0
    body = null
    code = Server.Processing
    message = There was an unhandled failure on the server. MessageClient has been invalidated.
    details = null
    rootCause = null
    body = null
    extendedData = null
    stackTrace for: java.lang.RuntimeException: MessageClient has been invalidated.
    flex.messaging.MessageClient.checkValid(MessageClient.java:894)
    flex.messaging.MessageClient.addSubscription(MessageClient.java:507)
    flex.messaging.services.messaging.SubscriptionManager.addSubscriber(SubscriptionManager.java:498)
    flex.messaging.services.MessageService.manageSubscriptions(MessageService.java:850)
    flex.messaging.services.MessageService.serviceCommand(MessageService.java:282)
    flex.messaging.MessageBroker.routeCommandToService(MessageBroker.java:1527)
    flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:855)
    flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
    flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
    flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:49)
    flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
    flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
    flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:274)
    flex.messaging.endpoints.BaseStreamingHTTPEndpoint.service(BaseStreamingHTTPEndpoint.java:470)
    flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:377)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
    org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1124)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)
    org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:116)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.basicauth.BasicProcessingFilter.doFilterHttp(BasicProcessingFilter.java:174)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter.doFilterHttp(DefaultLoginPageGeneratingFilter.java:86)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:277)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
    org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
    org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
    org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
    org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
    org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
    org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
    org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    org.mortbay.jetty.Server.handle(Server.java:324)
    org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
    org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:879)
    org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:741)
    org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:213)
    org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:403)
    org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:522)

    Thanks
    Krishna

  15. #15 Krishna
    on Feb 24th, 2009 at 12:03 pm

    while running the activeMQ batch file its shows this error…
    no response from the server to client

    INFO DemandForwardingBridge – localhost bridge to Unknown stopped
    INFO DiscoveryNetworkConnector – Establishing network connection between f
    rom vm://localhost to tcp://Admin:61616
    WARN DiscoveryNetworkConnector – Could not start network bridge between: v
    m://localhost and: tcp://Admin:61616 due to: java.net.UnknownHostException: Admi
    n

    thanks in advance

  16. #16 Kevin McCormack
    on Feb 24th, 2009 at 3:21 pm

    Hi Krishna,

    I’m not sure about the first error you report. It looks like there has been some kind of error on the server – “There was an unhandled failure on the server” – but the logs don’t say what it was.

    As for the second error, it is because Java cannot resolve the host name “Admin” that you have specified in the string “tcp://Admin:61616″. If it’s running locally, you should replace “Admin” with “localhost”. If it’s running remotely, you should check that you can ping the machine “Admin”.

  17. #17 Murthy.k
    on Feb 25th, 2009 at 6:04 am

    Hai kevin thanks…
    how will the server side recives the msg from client .
    In my application the msg from server is not recived by the client.

  18. #18 Kevin McCormack
    on Feb 25th, 2009 at 12:33 pm

    Hi Murthy.k,

    The JavaFeed or XmlFeed classes put messages in a JMS Topic provided by the ActiveMQ server. The BlazeDS server passes messages in this Topic onto Flex clients since the Flex clients cannot access the JMS Topics directly.

    If your client is not receiving messages, I’d look in the logs to see what is going wrong and maybe start again from scratch with this example – it should work more-or-less straight away after downloading it.

    Kevin.

  19. #19 Murthy.k
    on Feb 26th, 2009 at 9:55 am

    hi kevin thanks……
    can i send message from client?
    if can how can i get the message in server
    i have to do some validation with that message help

  20. #20 Murthy.k
    on Mar 2nd, 2009 at 10:19 am

    hi kevin thanks……
    can i send message from client?
    if can how can i get the message in server
    i have to do some validation with that message help

  21. #21 Arun
    on Mar 18th, 2009 at 1:18 pm

    Hi All,

    I have an application which is internally calling Jetty jar and starting the server.

    My requirement is to configure JMS in it.

    Could you please tell me what approach i should follow?

    can it be done through API? any other solution?

    Thanks in advance for your response.

    Arun.

  22. #22 Ilackiya
    on Apr 7th, 2009 at 1:01 pm

    Can you tell me where to place the BlazeDS.jar file in Jetty?
    Can you exaplain in detail about configuring Jetty with Bleze DS?

  23. #23 Kevin McCormack
    on Apr 8th, 2009 at 8:16 am

    @Arun – I guess you are running Jetty stand-alone instead of via Maven. In that case, the JMS configuration is pretty much exactly the same as that outlined in this post. You need to specify the jetty-env.xml file (see the “Configuring the Jetty JNDI resources” section) and the
    definitions to the web.xml file (also specified in this post. You’ll need to change the declarations if you use a different JMS server and you’ll almost certainly want to change the names of the queues/topics from the ones I’ve specified. Finally, you’ll need to add the JAR file from your JMS provider in the appropriate place (either Jetty classpath or WEB-INF/lib folder).

    @Ilackiya – the BlazeDS.jar file should go in the WEB-INF/lib folder of your webapp. This post already explains in a fair amount of detail the required Jetty configuration for BlazeDS. I suggest you download the example code from this post and get it working, then try to adapt it to your needs. If you need to change the Blaze configuration, for example, change the working example code via a process of trial and error till it does what you want it to do.

  24. #24 Chris
    on Jun 9th, 2009 at 2:20 pm

    Hi,

    I have a problem when starting Jetty through maven. I am running on Fedora 10 and have made sure my ActiveMQ is running. I am running the exact code from the download.

    However, when calling mvn jetty:run, I get this stack trace:
    [INFO] Starting jetty 6.1.14 …
    2009-06-10 21:11:32.325::INFO: jetty-6.1.14
    2009-06-10 21:11:32.612::WARN: EXCEPTION
    java.lang.NullPointerException
    at javax.naming.spi.NamingManager.getPlusPath(libgcj.so.9)
    at javax.naming.spi.NamingManager.getStateToBind(libgcj.so.9)
    at org.mortbay.naming.NamingContext.bind(NamingContext.java:339)
    at org.mortbay.naming.NamingContext.bind(NamingContext.java:417)
    at org.mortbay.naming.java.javaRootURLContext.(javaRootURLContext.java:80)
    at java.lang.Class.initializeClass(libgcj.so.9)
    at org.mortbay.naming.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:65)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.9)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.9)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(libgcj.so.9)
    at javax.naming.InitialContext.lookup(libgcj.so.9)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:57)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.configureDefaults(EnvConfiguration.java:101)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1214)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:460)
    at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:124)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:222)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:379)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:321)
    at org.mortbay.jetty.plugin.AbstractJettyRunMojo.execute(AbstractJettyRunMojo.java:205)
    at org.mortbay.jetty.plugin.Jetty6RunMojo.execute(Jetty6RunMojo.java:184)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(maven-core-2.0.4.jar.so)
    at org.apache.maven.DefaultMaven.doExecute(maven-core-2.0.4.jar.so)
    at org.apache.maven.DefaultMaven.execute(maven-core-2.0.4.jar.so)
    at org.apache.maven.cli.MavenCli.main(maven-core-2.0.4.jar.so)
    at java.lang.reflect.Method.invoke(libgcj.so.9)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
    2009-06-10 21:11:32.662::WARN: Failed startup of context org.mortbay.jetty.plugin.Jetty6PluginWebAppContext@35847ea1{/,/home/cjsceats/Download/trader-app/server/src/main/webapp}
    javax.naming.NameNotFoundException [remainingName: comp]
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:578)
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:680)
    at org.mortbay.naming.java.javaRootURLContext.lookup(javaRootURLContext.java:112)
    at javax.naming.InitialContext.lookup(libgcj.so.9)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:57)
    at org.mortbay.jetty.plus.webapp.EnvConfiguration.configureDefaults(EnvConfiguration.java:101)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1214)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:460)
    at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:124)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:222)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:379)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:321)
    at org.mortbay.jetty.plugin.AbstractJettyRunMojo.execute(AbstractJettyRunMojo.java:205)
    at org.mortbay.jetty.plugin.Jetty6RunMojo.execute(Jetty6RunMojo.java:184)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(maven-core-2.0.4.jar.so)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(maven-core-2.0.4.jar.so)
    at org.apache.maven.DefaultMaven.doExecute(maven-core-2.0.4.jar.so)
    at org.apache.maven.DefaultMaven.execute(maven-core-2.0.4.jar.so)
    at org.apache.maven.cli.MavenCli.main(maven-core-2.0.4.jar.so)
    at java.lang.reflect.Method.invoke(libgcj.so.9)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

  25. #25 Kevin McCormack
    on Jun 9th, 2009 at 2:41 pm

    Hi Chris,

    The base error you are getting is “javax.naming.NameNotFoundException [remainingName: comp]” which is a JNDI error. This is most probably caused by having non-matching ConnectionFactory and Topic declarations in the web.xml, jetty-env.xml and messaging-config.xml files. Check that the ConnectionFactory (jms/flex/ActiveMqConnectionFactory) and Topic (jms/stockQuoteTopic) declarations match up in the various files.

    Hope this helps,

    Kevin.

  26. #26 Chris
    on Jun 10th, 2009 at 1:02 am

    Hi Kevin,

    Thanks for the quick reply!

    I haven’t edited any of these files at all. I just checked and the declarations are all the same, except for the java:comp/env/ prefix in the messaging-config.xml, which I believe is necessary.

    I have also tried deleting my maven repository and re-running mvn jetty:run but I got the same result.

    Thanks,
    Chris

  27. #27 Kevin McCormack
    on Jun 10th, 2009 at 4:22 pm

    Hi Chris,

    I downloaded the source code from this post and deleted my maven repository and executed mvn jetty:run in the server folder. The Jetty server started up first time with no need to modify source or configuration files. I’ve enclosed a log below. I hate to resort to the “it works on my machine” defence but there’s not much I can do if I can’t reproduce the problem.

    I’d suggest you try this on another machine if possible. If it still fails to work, I could zip up my maven repo and send you it (15MB) to see if that helps.

    Kevin.

    The server logs:

    [INFO] Starting jetty 6.1.14 …
    2009-06-10 17:15:29.725::INFO: jetty-6.1.14
    2009-06-10 17:15:29.959::INFO: No Transaction manager found – if your webapp requires one, please configure one.
    [BlazeDS] BlazeDS – Community Edition: 3.0.0.544
    [BlazeDS] Endpoint my-polling-amf created with security: None
    at URL: http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling
    [BlazeDS] Endpoint my-amf created with security: None
    at URL: http://{server.name}:{server.port}/{context.root}/messagebroker/amf
    [BlazeDS] Endpoint my-streaming-amf created with security: None
    at URL: http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf
    [BlazeDS] MessageBroker id: __default__ classLoader is: the MessageBroker’s class loader and the context class loader (classLoader hashCode: 576658153 (parent hashCode: 277466206 (parent null))
    2009-06-10 17:15:30.962::INFO: Started SelectChannelConnector@0.0.0.0:9080
    [INFO] Started Jetty Server
    [INFO] Starting scanner at interval of 5 seconds.

  28. #28 chary1112004
    on Jun 16th, 2009 at 10:15 am

    Hi Kevin!
    I didn’t read all, but it is near my part which I must done. Thanks before!

    Chary!

  29. #29 Krishna
    on Jun 24th, 2009 at 2:54 pm

    hi kevin ,
    can i have store messages in client when there is no connection with server. and have to send messages once connection is established with server.

    is it possible

    thanks in advance……

  30. #30 Oleg
    on Jul 3rd, 2009 at 7:30 pm

    Ken,

    Thank you for the good example.
    I tried to follow your post to the letter.
    The only problem is that it doesn’t run for me (as also for a few people in the group).
    I do not receive any messages on the client.
    There is a lot of activity in the console which started Jetty.
    But nothing comes to ActiveMQ 5.2.0 console, remains static since started:

    INFO TransportServerThreadSupport – Listening for connections at: tcp://ok-6400:61616
    INFO TransportConnector – Connector openwire Started

    INFO NetworkConnector – Network Connector default-nc Started
    INFO BrokerService – ActiveMQ JMS Message Broker (localhost, ID:ok-6400-1473-1246643551031-0:0) started
    INFO log – Logging to org.slf4j.impl.JCLLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog
    INFO log – jetty-6.1.9
    INFO WebConsoleStarter – ActiveMQ WebConsole initialized.
    INFO /admin – Initializing Spring FrameworkServlet ‘dispatcher’
    INFO log – ActiveMQ Console at http://0.0.0.0:8161/admin
    INFO log – ActiveMQ Web Demos at http://0.0.0.0:8161/demo
    INFO log – RESTful file access application at http://0.0.0.0:8161/fileserver
    INFO log – Started SelectChannelConnector@0.0.0.0:8161
    INFO TransportConnector – Connector vm://localhost Started

    Can the fact that it replaced localhost with my machine name (ok-6400) tcp://ok-6400:61616 be a problem ?

    Nothing is happening in the JavaFeed console either.

    Client URL shows Flex app (no data feed received):
    http://localhost:9080/trader-app-client-debug/traderdesktop.html

    Please help!

    TIA,
    Oleg.

  31. #31 Kevin McCormack
    on Jul 6th, 2009 at 11:40 am

    @Krishna

    There should be no problem storing the messages on the client – you could use a standard Flex data structure to store them and then when a connection is established to the server, you could send the messages. If the user closes the Flex application, they will lose all unsent messages though.

  32. #32 Kevin McCormack
    on Jul 6th, 2009 at 12:12 pm

    @Oleg,

    In the JavaFeed console window, you should see output like this below:

    log4j:WARN No appenders could be found for logger (org.apache.activemq.transport.WireFormatNegotiator).
    log4j:WARN Please initialize the log4j system properly.
    XOM
    WMT
    GM
    CVX
    COP
    GE
    C
    AIG
    GOOG
    ADBE
    JBLU
    COKE
    GENZ
    YHOO
    IBM
    BA
    SAP
    MOT
    VZ
    MCD

    If you don’t, then I’d check the /data/activemq.log and /data/wrapper.log files under the ActiveMQ installation.

    First verify that ActiveMQ is working ok and then worry about getting it to work with Flex.

    For what it’s worth, I’ve used ‘localhost’ as the URL on both linux and Windows machines and it seems to work ok but try changing the URL to your machine’s DNS name in the FeedThread.java file if you think it might make a difference.

  33. #33 Oleg
    on Jul 8th, 2009 at 4:39 pm

    Kevin,

    I do get exactly that output in JavaFeed console as you specified.

    But nothing is happening in ActiveMQ console after it is started.
    Do I need to configure something for that to happen ?

    How do I verify that ActiveMQ is working OK ?
    (it did work fine for some other JMS sample)

    Please help !

    TIA,
    Oleg.

  34. #34 Kevin McCormack
    on Jul 9th, 2009 at 8:49 am

    Hi Oleg,

    If you go to http://localhost:8161/admin/topics.jsp you should be able to see the statistics for the stockQuoteTopic. The number of messages sent should increase while the JavaFeed class is running. You should see the Flex app consuming the messages if all goes well.

    Cheers,

    Kevin.

  35. #35 Oleg
    on Jul 9th, 2009 at 4:46 pm

    Kevin,

    I restarted everything again and tried that ActiveMQ console.
    For the topic stockQuoteTopic it shows:
    Number of Consumers: 5 [why 5, not 1?]
    Messages Sent: 484
    Messages Received: 1829
    and the sent/received is growing fast.
    However still see nothing on Flex Console,
    despite lots of activity in the Jetty console.
    Changing channel doesn’t help.

    Do I need to do anything there ?

    I have not changed anything in the code, followed your instructions.

    Please advise.

    Thank you,
    Oleg.

  36. #36 Oleg
    on Jul 9th, 2009 at 5:44 pm

    Hmm,

    Despite a large number of Received messages in ActiveMQ console
    (around Sent x 5), still see no data in Flex console.
    Tried FF3.5, IE8, Chrome.

    Does Messages Received count mean consumed by the Consumer client and Acknowledged?

    But why is it 5 messages Received per client instance ?

    Can we conclude that Flex client does receive message but fails to display the data for some reason ?
    It shows endpoint http://localhost:9080/messagebroker/streamingamf or amfpolling and
    channel class: mx.messaging.channels::StremingAMFChannel or AMFChannel. Is that correct ?
    I have not changed anything in configuration or the code from downloaded.

    Please help !

    Thank you,
    Oleg.

  37. #37 Oleg
    on Jul 9th, 2009 at 10:07 pm

    Oops, I meant to say that I still do not get any data in Flex client (not console), just 0′s and blanks.
    Any idea ?

    Also, my goal is to deploy your sample on JBoss5,
    (maybe with first moving it to Tomcat6 as a transition).
    Could you please describe how to do that ?

    TIA,
    Oleg.

  38. #38 Kevin McCormack
    on Jul 10th, 2009 at 9:02 am

    Hi Oleg,

    It seems like BlazeDS is reading the messages from the ActiveMQ Topic. There are 5 times as many messages recieved per client instance because there are 5 stock symbols initially configured in the Flex client.

    If I was you, I’d try using the debugger in Flex Builder to see what is going on in the Flex code. From what you have told me, it seems that BlazeDS is reading the messages but I cannot be certain that the Flex client is communicating properly with BlazeDS and receiving the message. Debugging will help determine this.

    As for deploying on another application server, it should be pretty simple. You’ll have to work out what the deployment descriptor requirements are for Tomcat/JBoss – the equivelents of jetty-env.xml – and package the whole thing up into a WAR file that you deploy on the application server. You do the later by executing ‘mvn package’ in the console window when in the root folder of the server project.

    Hope this helps,

    Kevin.

  39. #39 Oleg
    on Jul 11th, 2009 at 4:07 am

    Kevin,

    How do I debug Flex app on Jetty ?
    I didn’t find Jetty among suggested J2EE servers in FlexBuilder3.

    I tried to build WAR, and deploy it to Tomcat6 [BlazeDS3.2 turnkey testdrive] (webapps/trader-app).
    I also added the following trader-app.xml to tomcat/conf/Catalina/localhost dir:

    or is it supposed to be called “wac” ?

    That turnkey Testdrive has ActiveMQ4.1.1 built in.
    But as I start it app, and go to:
    http://localhost:8400/trader-app-client-debug/traderdesktop.html or
    http://localhost:8400/trader-app/traderdesktop.html,
    it brings up Flex client with no data.

    I also tried http://localhost:8161/admin/topics.jsp,
    but FF3 shows “Unable to connect to server localhost:8161″
    Am I supposed to configure Tomcat to open that port ?
    Or configure ActiveMQ to use it ?

    What would you recommend ?

    TIA,
    Oleg.

  40. #40 Kevin McCormack
    on Jul 13th, 2009 at 8:52 am

    Hi Oleg,

    I haven’t got access to a copy of Flex Builder right now but if I remember correctly, the normal debugging procedure won’t work because you are running the client outside Flex Builder. Follow the remote debugging steps in this article – http://blogs.4point.com/armaghan.chaudhary/2009/04/remote-debugging-using-flex-builder-ide.html.

    I’ve not run this example on Tomcat 6 so I’m afraid you’re on your own for that. Sorry!

    I’ve also not used ActiveMQ in the turnkey distribution. However, it is quite possible that it runs on a different port than 8161. Check out the documentation for ActiveMQ4.1.1 and the turnkey distribution.

  41. #41 Oleg
    on Jul 14th, 2009 at 5:38 pm

    Kevin,

    I will try remote debugging.

    One clue it that XmlFeed works fine, JavaFeed doesn’t work.

    Also, here is a Context XML file trader-app.xml which I put on Tomcat into tomcat/conf/Catalina/localhost dir:

    Does it look right to you ?
    or is the file & context path supposed to be called “wac” ?
    correct ?

    I do not understand that “wac” in your configuration.
    Is it referred to somewhere in the code?

    Please advise.

    Thank you,
    Oleg.

  42. #42 Oleg
    on Jul 14th, 2009 at 9:56 pm

    Kevin,

    So the problem I got is natural: there are 2 different feeds (Java Object and XML String), and you put line in traderdesktop.mxml:
    consumer.addEventListener(MessageEvent.MESSAGE, xmlMessageHandler);
    That means that JavaFeed won’t work without recompiling your Flex code. JavaFeed is much more natural for our case, would be a better default.

    So how do I recompile Flex code & rebuild SWF & redeploy to Jetty ?
    I tried to create SWF manually in FB and then copy new SWF to replace all existing ones. Didn’t work in some directories, and “mvn deploy” produces error:
    Failed to configure plugin parameters for: org.apache.maven.plugins:maven-deploy-plugin:2.4
    So it still running with old XML feed.

    Please advise.

    Also, there is a small bug: always Change=Last value, shouldn’t change show the delta ?

    TIA,
    Oleg.

  43. #43 Kevin McCormack
    on Jul 15th, 2009 at 9:01 am

    Hi Oleg,

    When you say that XmlFeed works fine, you mean that the Flex client updates the stock prices when using XmlFeed? Remember, that you have to make code changes – specifically 83 of traderdesktop.mxml – in the Flex client depending on whether you use the XmlFeed or JavaFeed classes to push data to the JMS Topics. You cannot use both with the same Flex client code.

    I can’t see a Context XML file attached. The “wac” thing is Jetty-specific – I think it means Web Application Context. It is not relevant to Tomcat configuration.

  44. #44 Oleg
    on Jul 20th, 2009 at 3:45 pm

    Kevin,

    >When you say that XmlFeed works fine, you mean that the Flex >client updates the stock prices when using XmlFeed?
    Yes, that is true.

    But when I tried to switch to JavaFeed in line 83, wasn’t able to redeploy new SWFs to Jetty (still – no data in Flex client). How do I do that, any good MVN command to do that ?

    I think, it would be a great enhancement to make Java/XML feed switch on the screen (e.g. dropdown or toggle button or radiobutton).

    I tried to publish that Context XML twice, for some reason it is not coming through. :-(
    OK, here it is commented out [just in case]:


    TIA,
    Oleg.

  45. #45 krishna
    on Nov 25th, 2009 at 3:18 pm

    hi kevin,
    its working fine in my proj when it was run in jetty server its working. when i deployed in tomcat server its some null pointer exception due to jeety-env.xml

    can u help me……..
    thanks in advance..

  46. #46 Leon
    on Feb 26th, 2010 at 1:44 pm

    I have downloaded Jetty 7.0.1 distribution version and have started it with java -jar start.jar

    It then tries to extract the blazeds.war file. But then it comes with the message: “NO JSP Support for /blazeds, did not find org.apache.jasper.servlet.JspServlet”

    In Tomcat there is a jasper.jar file where the JspServlet is located. But why do I need tomcat dependencies in Jetty?

  47. #47 Leon
    on Mar 9th, 2010 at 3:32 pm

    I am puzzeling for days now. I always get this NameNotFoundException. I use the downloaded jetty-env.xml and web.xml etc….

    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter due to the following error: javax.naming.NameNotFoundException; remaining name ‘env/jms/flex/
    ActiveMqConnectionFactory’
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.
    [BlazeDS]The corresponding MessageClient for JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being invalidated
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB644E3A-C80F-01D2-4483-AAD2A6102B6F
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB644E3A-C80F-01D2-4483-AAD2A6102B6F
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter due to the following error: javax.naming.NameNotFoundException; remaining name ‘env/jms/flex/
    ActiveMqConnectionFactory’
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.
    [BlazeDS]The corresponding MessageClient for JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being invalidated
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB64DF39-EC3B-1734-032A-3F658A0DC8F1
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB64DF39-EC3B-1734-032A-3F658A0DC8F1
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter due to the following error: javax.naming.NameNotFoundException; remaining name ‘env/jms/flex/
    ActiveMqConnectionFactory’
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.
    [BlazeDS]The corresponding MessageClient for JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being invalidated
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB64DF85-9B5F-E6D7-370A-796EBF274212
    [BlazeDS]Routing message to FlexClient id:DB644A0F-E30D-702E-7D62-B60165762337′, MessageClient id: DB64DF85-9B5F-E6D7-370A-796EBF274212
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is being removed from the JMS adapter
    [BlazeDS]JMS consumer for JMS destination ‘java:comp/env/jms/stockQuoteTopic’ is stopping.

  48. #48 Leon
    on Mar 9th, 2010 at 3:36 pm

    Hello Kevin McCormack,

    Can you also provide a turnkey jetty download with the example in it?

    This would help me very much.

    thnx,
    Leon

Leave a Comment