« Ensuring Windows Services can access Novell NetWare directories - Dashboards… Flex’s ‘Sweet Spot’ »

[Tunkey] BlazeDS + JMS + ActiveMQ

1 August 2008

I spent some time this week with BlazeDS and JMS. I wanted to integrate a Flex RIA with some [existing] backend Java classes. One goal was to interface the two in a loosely coupled fashion, enter Java Message Service (JMS).

The RIA uses a mx:producer to publish messages to a JMS topic which the backend Java class is listening in on [consuming] elsewhere in the enterprise. I used an ‘external install’ of ActiveMQ.

I downloaded the turnkey BlazeDS server to get things rolling.

I came across a few great posts in looking into this…

Michael Martin’s Simplified BlazeDS and JMS

Christophe Coenraets
Flex and JMS: Portfolio Viewer (LCDS jRun)
30 Minutes Flex Test-Drive for Java Developers (FDS)

To be helpful, I’ve included some error messages and their causes:

Flex Runtime Error:
There was an unhandled failure on the server. MessageClient has been invalidated.
Cause: ActiveMQ not running.

Flex Runtime Error:
Client.Message.Encoding
Type ‘com.dl.samples.PersonVO’ not found.
Cannot create class of type ‘com.dl.samples.PersonVO’.
Cause: Java classes not on server.

Java Runtime Error
javax.naming.NameNotFoundException: messageTopic
at org.apache.activemq.jndi.ReadOnlyContext.lookup(ReadOnlyContext.java:225)
at javax.naming.InitialContext.lookup(Unknown Source)
at Chat.(Chat.java:55)
at Chat.main(Chat.java:27)
Cause: jndi.properties not present for java class

Java Runtime [BlazeDS] Error
[BlazeDS] JMS consumer for JMS destination ‘[destinationName]’ is being removed from the JMS adapter due to the following error: Name jms is not bound in this Context
[BlazeDS] JMS consumer for JMS destination ‘[destinationName]’ is stopping.
[BlazeDS] The corresponding MessageClient for JMS consumer for JMS destination ‘[destinationName]’ is being invalidated

Cause: context.xml Resource names do not match messaging-config.xml connection-factory / destination-jndi-name tags. (i.e. the ‘org.apache.activemq.ActiveMQConnectionFactory’ resource name in context.xml should match the connection-factory value in messaging-config and the ‘org.apache.activemq.command.ActiveMQTopic’ resource name in context.xml should match the destination-jndi-name value in messaging-config).

Adding the logging pattern ‘Service.Message.JMS’ to your services-config.xml can be very helpful in debugging BlazeDS JMS problems.

Here are the config files

C:/blazeds/tomcat/webapps/MyApp/WEB-INF/flex/services-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<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://localhost:8400/BlazeTest/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
</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>
<pattern>Service.Message.JMS</pattern>
</filters>
</target>
</logging>
</services-config>

C:/blazeds/tomcat/webapps/MyApp/WEB-INF/flex/messaging-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
<destination id="simpleJMS">
<properties>
<jms>
<destination-type>Topic</destination-type>
<!--<message-type>javax.jms.TextMessage</message-type>-->
<message-type>javax.jms.ObjectMessage</message-type>
<connection-factory>java:comp/env/TopicConnectionFactory</connection-factory>
<destination-jndi-name>java:comp/env/messageTopic</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-amf"/>
</channels>
<adapter ref="jms"/>
</destination>
</service>

C:/blazeds/tomcat/webapps/MyApp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>BlazeDS</display-name>
<description>BlazeDS Application</description>
<!-- 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>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

C:/blazeds/tomcat/webapps/MyApp/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/BlazeTest">
<Resource name="TopicConnectionFactory"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="tcp://localhost:61616"
brokerName="myBroker"/>
<Resource name="messageTopic"
type="org.apache.activemq.command.ActiveMQTopic"
description="a simple topic"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="messageTopic"/>
</Context>

Using the above messaging-config’s destination the message will come across as an ObjectMessage in Java :)


Leave a reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word