Hi all friends,

I spent two days solving this problem and because there is not so
complex informations about this in the internet, I find this helpful.

I hope, this will help.

I need to connect from Tomcat web application into the standalone
ActiveMQ broker. I repeat -- standalone broker. But I found several
problems. First, the configuration:

Sun Java 5 (06)
Apache Tomcat 5.5.15
ActiveMQ 4.0-M4

The first:
- start ActiveMQ using the bin/activemq bash script (sorry, I'm using
Linux, for windows use appropriate bat/cmd scripts and remembere the
(back)slash hell).
So, You can connect to the broker using jconsole:

jconsole service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi

Second, start tomcat with the simple servlet sending TextMessage using
JMS objects obtained from JNDI.

But, there is a bug, in the M4 ActiveMQ distribution.

Then you close the connection (the close() method), your connection to
the broker is closed but the `Connection already closed' Exception
during `cleanup()' is thrown. This exception does not throws to the
Servlet code itselfs, but is secreted in the tomcat's another thread,
so you can see it only in the log or in the Eclipse "console".

WARNING: Cleanup failed
org.apache.activemq.ConnectionClosedException: The connection is already closed
        at 
org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1030)
        at 
org.apache.activemq.ActiveMQConnection.cleanup(ActiveMQConnection.java:1191)
        at 
org.apache.activemq.ActiveMQConnection.transportFailed(ActiveMQConnection.java:1585)
        at 
org.apache.activemq.ActiveMQConnection.onException(ActiveMQConnection.java:1338)
        at 
org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:102)
        at 
org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:102)
        at 
org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:102)
        at 
org.apache.activemq.transport.TransportSupport.onException(TransportSupport.java:90)
        at 
org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:149)
        at java.lang.Thread.run(Thread.java:595)

And, if you does not call the close() method, no Exception is thrown
and the connection (the socket) will stay connected. If you trigger
the servlet (for ex. using the GET program), you will see in the
jconsole more and more unused connections.

The solution is simple: Upgrade ActiveMQ to the latests SNAPSHOT.

The latest SNAPSHOT is working very very good.

And one note. You can see in the ActiveMQ log the Exception:

java.lang.ClassNotFoundException: mx4j.tools.naming.NamingService

Simply download latest binary distribution of the mx4j project and
copy the mx4j-tools.jar into the $ACTIVEMQ_HOME/lib. Cool.


And, If you are looking for something like this problem (Tomcat +
ActiveMQ + JMS + JNDI), here is my web application configuration
files:

META-INF/context.xml:
<Context>
...
        <Resource
                name="jms/ConnectionFactory"
                auth="Container"
                type="org.apache.activemq.ActiveMQConnectionFactory"
                description="JMS Connection Factory"
                factory="org.apache.activemq.jndi.JNDIReferenceFactory"
                brokerURL="tcp://ws:61616"
                brokerName="localhost"
                useEmbeddedBroker="false" />
        <Resource
                name="jms/Test"
                auth="Container"
                type="org.apache.activemq.command.ActiveMQQueue"
                factory="org.apache.activemq.jndi.JNDIReferenceFactory"
                physicalName="TEST" />
...
</Context>


WEB-INF/web.xml:
...
        <resource-env-ref>
               
<resource-env-ref-name>jms/ConnectionFactory</resource-env-ref-name>
               
<resource-env-ref-type>javax.jms.ConnectionFactory</resource-env-ref-type>
        </resource-env-ref>

        <resource-env-ref>
                <resource-env-ref-name>jms/Test</resource-env-ref-name>
                <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
        </resource-env-ref>
...

And the peace of Servlet code using this configuration:
...
               try {
                        InitialContext ic = new InitialContext();
                        Context ctx = (Context) ic.lookup("java:comp/env");

                        ConnectionFactory cf = (ConnectionFactory)
ctx.lookup("jms/ConnectionFactory");
                        Connection conn = (Connection) cf.createConnection();
                        conn.start();

                        Session s = conn.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
                        Destination d = (Destination) ctx.lookup("jms/Test");

                        MessageProducer mp = s.createProducer(d);
                        mp.setDeliveryMode(DeliveryMode.PERSISTENT);

                        TextMessage tm = s.createTextMessage();
                        tm.setText("Foo");

                        mp.send(tm);

                        tm = s.createTextMessage();
                        tm.setText("Bar");

                        mp.send(tm);

                        conn.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }
 ...


So, have a nice day, I hope, this can help

PETR

Reply via email to