You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by Hycel <hy...@gmail.com> on 2006/04/05 22:50:33 UTC

Cleanup failed JMS Exception

I am using ActiveMQ with the Spring framework and the Quartz Scheduler.  On
the server, I’ve started an ActiveMQ broker.  Also on the server I have a
job dispatcher application that reads job schedules from a MySQL database
and starts a Quartz Scheduler instance.  When a job is created, it uses
ActiveMQ to dispatch job information to a reporting queue.  I have a client
machine that is waiting to receive messages from the reporting queue.  Once
it receives a message it launches a new reporting thread.  

Up until three days ago, my code was working perfectly.  A job would be
created, a map of messages would be sent to the reporting queue, the client
dispatcher would successfully retrieve the message from the reporting queue
and launch a new reporting thread which runs a report.  However, another
programmer did a code check in which modified some of my code.  Since he did
his code check in, each time we run our test application we are getting the
following exception each time a message is sent or retrieved from the queue:

[WARN,ActiveMQConnection,tcp://localhost/127.0.0.1:61616] Cleanup failed
javax.jms.JMSException: Cannot write to the stream any more it has already
been closed
	at
org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:57)
	at
org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1043)
	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)
Caused by: java.io.EOFException: Cannot write to the stream any more it has
already been closed
	at
org.apache.activemq.transport.tcp.TcpBufferedOutputStream.checkClosed(TcpBufferedOutputStream.java:131)
	at
org.apache.activemq.transport.tcp.TcpBufferedOutputStream.write(TcpBufferedOutputStream.java:69)
	at java.io.DataOutputStream.writeInt(DataOutputStream.java:180)
	at
org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:169)
	at
org.apache.activemq.transport.tcp.TcpTransport.oneway(TcpTransport.java:117)
	at
org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:90)
	at
org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:65)
	at
org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:44)
	at
org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorrelator.java:54)
	at
org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1041)
	... 9 more

We have gone through and tried to figure out what slice of code he may have
added or modified that could be causing this exception. But, after three
days, we have not been able to determine why we are getting this exception. 
Here are few givens:

The class we use to send messages to a queue is the following:

public class QueueMessage implements Serializable {
    private Map<String, String> parameters = new HashMap<String, String>();

    public QueueMessage() {
    }

    public String getParameterValue(String name) {
        return parameters.get(name);
    }

    public void addParameter(String name, String value) {
        parameters.put(name, value);
    }

    public boolean containsKey(String name) {
        return parameters.containsKey(name);
    }

    public String toString() {
        final StringBuilder builder = new StringBuilder();

        final Set<Map.Entry<String, String>> set = parameters.entrySet();
        for (Map.Entry<String, String> entry : set) {
            builder.append("\nname=");
            builder.append(entry.getKey());
            builder.append(" value=");
            builder.append(entry.getValue());
        }
        return builder.toString();
    }
}

The class that actually does all of the work of sending or retrieving a
QueueMessage object is the following:

public class QueueSenderReceiver {
    private final String appContext =
"./config/jmsUtils/ApplicationContext.xml";
    private final String clientContext =
"./config/jmsUtils/ClientContext.xml";
    private final String templateName = "jmsTemplate";

    private final JmsTemplate template;
    private final ApplicationContext ctx;

    public QueueSenderReceiver() {
        final String[] configFiles = new String[2];
        configFiles[0] = appContext;
        configFiles[1] = clientContext;

        ctx = new FileSystemXmlApplicationContext(configFiles);
        template = (JmsTemplate) ctx.getBean(templateName);
    }

    /**
     * Used to send any type of object over a queue.
     * 
     * @param destinationName name of the queue to send the object to.
     * @param object used to send a QueueMessage and other objects.
     */
    public void send(String destinationName, final Object object) {
        final Destination destination = (Destination)
ctx.getBean(destinationName);
        template.convertAndSend(destination, object);
    }

    public void send(String destinationName, final String message) {
        final Destination destination = (Destination)
ctx.getBean(destinationName);
        template.send(destination, new MessageCreator() {
            public Message createMessage(Session session) throws
JMSException {
                return session.createTextMessage(message);
            }
        });
    }

    public Object receive(String destinationName) {
        final Destination destination = (Destination)
ctx.getBean(destinationName);
        template.getReceiveTimeout();
        return template.receiveAndConvert(destination);
    }
}

The Spring ApplicationContext.xml file contains the following:

<beans>
    <!-- configure connection factory -->
    <bean id="connectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL">
            <value>tcp://localhost:61616</value>
        </property>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory">
            <ref local="connectionFactory"/>
        </property>
    </bean>
</beans>

The Spring ClientContext.xml file contains the following:

<beans>
    <bean id="job.auditor"
class="org.apache.activemq.command.ActiveMQQueue">
        <!-- Set the Queue Name -->
        <constructor-arg index="0">
            <value>JobAuditQueue</value>
        </constructor-arg>
    </bean>

    <bean id="report.dispatch.1"
class="org.apache.activemq.command.ActiveMQQueue">
        <!-- Set the Queue Name -->
        <constructor-arg index="0">
            <value>ReportDispatcherQueue</value>
        </constructor-arg>
    </bean>

    <bean id="feed.dispatch.1"
class="org.apache.activemq.command.ActiveMQQueue">
        <!-- Set the Queue Name -->
        <constructor-arg index="0">
            <value>FeedDispatcherQueue</value>
        </constructor-arg>
    </bean>
</beans>

The current version of ActiveMQ I’m using is 4.0-M4.

I hope this is enough information to us find out why we may be getting this
exception.  Any help from anyone would be much appreciated.

Thanks.

--
View this message in context: http://www.nabble.com/Cleanup-failed-JMS-Exception-t1402113.html#a3773076
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Cleanup failed JMS Exception

Posted by James Strachan <ja...@gmail.com>.
You're welcome! :)

James

On 4/6/06, Hycel <hy...@gmail.com> wrote:
>
> You are correct.  I followed the advice of wrappiing the
> ActiveMQConnectionFactory with the PooledConnectionFactory.  It's working
> properly now, without throwing any exceptions.
>
> Thank you very much for your advice concerning this matter.
> --
> View this message in context: http://www.nabble.com/Cleanup-failed-JMS-Exception-t1402113.html#a3782817
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


--

James
-------
http://radio.weblogs.com/0112098/

Re: Cleanup failed JMS Exception

Posted by James Strachan <ja...@gmail.com>.
BTW please be aware that the PooledConnectionFactory is only useful
for sending messages; for consuming  messages you should not really
use JmsTemplate either. I suggest either using the JMS API to create a
consumer, or using Jencks..

http://jencks.org/

as using JmsTemplate causes a new connection, session and consumer to
be created for every message you consume; which is really slow and
inefficient.

James

On 4/6/06, Hycel <hy...@gmail.com> wrote:
>
> You are correct.  I followed the advice of wrappiing the
> ActiveMQConnectionFactory with the PooledConnectionFactory.  It's working
> properly now, without throwing any exceptions.
>
> Thank you very much for your advice concerning this matter.
> --
> View this message in context: http://www.nabble.com/Cleanup-failed-JMS-Exception-t1402113.html#a3782817
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


--

James
-------
http://radio.weblogs.com/0112098/

Re: Cleanup failed JMS Exception

Posted by Hycel <hy...@gmail.com>.
You are correct.  I followed the advice of wrappiing the
ActiveMQConnectionFactory with the PooledConnectionFactory.  It's working
properly now, without throwing any exceptions.

Thank you very much for your advice concerning this matter.  
--
View this message in context: http://www.nabble.com/Cleanup-failed-JMS-Exception-t1402113.html#a3782817
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Cleanup failed JMS Exception

Posted by James Strachan <ja...@gmail.com>.
My first tip would be, try upgrading to 4.0-RC2. I'd also recommend reading

http://activemq.org/JmsTemplate+Gotchas

As without properly using a pooling strategy, JmsTemplate is one of
the worst way so of working with JMS.

Other than that there's not much to go on really.

James

On 4/5/06, Hycel <hy...@gmail.com> wrote:
>
> I am using ActiveMQ with the Spring framework and the Quartz Scheduler.  On
> the server, I've started an ActiveMQ broker.  Also on the server I have a
> job dispatcher application that reads job schedules from a MySQL database
> and starts a Quartz Scheduler instance.  When a job is created, it uses
> ActiveMQ to dispatch job information to a reporting queue.  I have a client
> machine that is waiting to receive messages from the reporting queue.  Once
> it receives a message it launches a new reporting thread.
>
> Up until three days ago, my code was working perfectly.  A job would be
> created, a map of messages would be sent to the reporting queue, the client
> dispatcher would successfully retrieve the message from the reporting queue
> and launch a new reporting thread which runs a report.  However, another
> programmer did a code check in which modified some of my code.  Since he did
> his code check in, each time we run our test application we are getting the
> following exception each time a message is sent or retrieved from the queue:
>
> [WARN,ActiveMQConnection,tcp://localhost/127.0.0.1:61616] Cleanup failed
> javax.jms.JMSException: Cannot write to the stream any more it has already
> been closed
>         at
> org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:57)
>         at
> org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1043)
>         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)
> Caused by: java.io.EOFException: Cannot write to the stream any more it has
> already been closed
>         at
> org.apache.activemq.transport.tcp.TcpBufferedOutputStream.checkClosed(TcpBufferedOutputStream.java:131)
>         at
> org.apache.activemq.transport.tcp.TcpBufferedOutputStream.write(TcpBufferedOutputStream.java:69)
>         at java.io.DataOutputStream.writeInt(DataOutputStream.java:180)
>         at
> org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:169)
>         at
> org.apache.activemq.transport.tcp.TcpTransport.oneway(TcpTransport.java:117)
>         at
> org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:90)
>         at
> org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:65)
>         at
> org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:44)
>         at
> org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorrelator.java:54)
>         at
> org.apache.activemq.ActiveMQConnection.asyncSendPacket(ActiveMQConnection.java:1041)
>         ... 9 more
>
> We have gone through and tried to figure out what slice of code he may have
> added or modified that could be causing this exception. But, after three
> days, we have not been able to determine why we are getting this exception.
> Here are few givens:
>
> The class we use to send messages to a queue is the following:
>
> public class QueueMessage implements Serializable {
>     private Map<String, String> parameters = new HashMap<String, String>();
>
>     public QueueMessage() {
>     }
>
>     public String getParameterValue(String name) {
>         return parameters.get(name);
>     }
>
>     public void addParameter(String name, String value) {
>         parameters.put(name, value);
>     }
>
>     public boolean containsKey(String name) {
>         return parameters.containsKey(name);
>     }
>
>     public String toString() {
>         final StringBuilder builder = new StringBuilder();
>
>         final Set<Map.Entry<String, String>> set = parameters.entrySet();
>         for (Map.Entry<String, String> entry : set) {
>             builder.append("\nname=");
>             builder.append(entry.getKey());
>             builder.append(" value=");
>             builder.append(entry.getValue());
>         }
>         return builder.toString();
>     }
> }
>
> The class that actually does all of the work of sending or retrieving a
> QueueMessage object is the following:
>
> public class QueueSenderReceiver {
>     private final String appContext =
> "./config/jmsUtils/ApplicationContext.xml";
>     private final String clientContext =
> "./config/jmsUtils/ClientContext.xml";
>     private final String templateName = "jmsTemplate";
>
>     private final JmsTemplate template;
>     private final ApplicationContext ctx;
>
>     public QueueSenderReceiver() {
>         final String[] configFiles = new String[2];
>         configFiles[0] = appContext;
>         configFiles[1] = clientContext;
>
>         ctx = new FileSystemXmlApplicationContext(configFiles);
>         template = (JmsTemplate) ctx.getBean(templateName);
>     }
>
>     /**
>      * Used to send any type of object over a queue.
>      *
>      * @param destinationName name of the queue to send the object to.
>      * @param object used to send a QueueMessage and other objects.
>      */
>     public void send(String destinationName, final Object object) {
>         final Destination destination = (Destination)
> ctx.getBean(destinationName);
>         template.convertAndSend(destination, object);
>     }
>
>     public void send(String destinationName, final String message) {
>         final Destination destination = (Destination)
> ctx.getBean(destinationName);
>         template.send(destination, new MessageCreator() {
>             public Message createMessage(Session session) throws
> JMSException {
>                 return session.createTextMessage(message);
>             }
>         });
>     }
>
>     public Object receive(String destinationName) {
>         final Destination destination = (Destination)
> ctx.getBean(destinationName);
>         template.getReceiveTimeout();
>         return template.receiveAndConvert(destination);
>     }
> }
>
> The Spring ApplicationContext.xml file contains the following:
>
> <beans>
>     <!-- configure connection factory -->
>     <bean id="connectionFactory"
> class="org.apache.activemq.ActiveMQConnectionFactory">
>         <property name="brokerURL">
>             <value>tcp://localhost:61616</value>
>         </property>
>     </bean>
>
>     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
>         <property name="connectionFactory">
>             <ref local="connectionFactory"/>
>         </property>
>     </bean>
> </beans>
>
> The Spring ClientContext.xml file contains the following:
>
> <beans>
>     <bean id="job.auditor"
> class="org.apache.activemq.command.ActiveMQQueue">
>         <!-- Set the Queue Name -->
>         <constructor-arg index="0">
>             <value>JobAuditQueue</value>
>         </constructor-arg>
>     </bean>
>
>     <bean id="report.dispatch.1"
> class="org.apache.activemq.command.ActiveMQQueue">
>         <!-- Set the Queue Name -->
>         <constructor-arg index="0">
>             <value>ReportDispatcherQueue</value>
>         </constructor-arg>
>     </bean>
>
>     <bean id="feed.dispatch.1"
> class="org.apache.activemq.command.ActiveMQQueue">
>         <!-- Set the Queue Name -->
>         <constructor-arg index="0">
>             <value>FeedDispatcherQueue</value>
>         </constructor-arg>
>     </bean>
> </beans>
>
> The current version of ActiveMQ I'm using is 4.0-M4.
>
> I hope this is enough information to us find out why we may be getting this
> exception.  Any help from anyone would be much appreciated.
>
> Thanks.
>
> --
> View this message in context: http://www.nabble.com/Cleanup-failed-JMS-Exception-t1402113.html#a3773076
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


--

James
-------
http://radio.weblogs.com/0112098/