[
https://issues.apache.org/jira/browse/AMQ-3593?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Timothy Bish closed AMQ-3593.
-----------------------------
Resolution: Cannot Reproduce
There's no reproducible test case and no other reports of seeing this. Testing
with a recent 5.9-SNAPSHOT might show if the fixes for the concurrent store and
dispatch functionality when using message groups is your issue or not.
> Messages with empty marshalledProperties
> ----------------------------------------
>
> Key: AMQ-3593
> URL: https://issues.apache.org/jira/browse/AMQ-3593
> Project: ActiveMQ
> Issue Type: Bug
> Affects Versions: 5.4.2, 5.5.1
> Environment: * OS: Linux version 2.6.9-67.0.4.ELlargesmp
> ([email protected]) (gcc version 3.4.6 20060404 (Red
> Hat 3.4.6-9)) #1 SMP Fri Jan 18 05:10:01 EST 2008
> * JVM (-server option in use): Java(TM) SE Runtime Environment (build
> 1.6.0_24-b07) Java HotSpot(TM) Server VM (build 19.1-b02, mixed mode)
> Reporter: Luca Zenti
> Attachments: PublisherAndBroker.java, Subscriber.java
>
>
> Sometimes messages arrive on the client with an empty "marshalledProperties"
> field. This causes an exception trying to unmarshall them.
> This happens very rarely, but we've got at least 2-3 cases a day per
> subscriber in our production environment.
> We use a broker embedded with a server component that publishes messages on
> topics. The subscribers are remote.
> I was unable to replicate the problem on my Windows workstation, nor to
> reproduce it precisely.
> Attached you can find a simple pair of programs (the publisher and the
> subscriber) that can reproduce the issue within 5 minutes at most on my
> environment. This happens only if at least one of the subscribers runs on a
> remote machine and it seems to happen quickly with more clients connected.
> The publishing program has a command line arguments that allows to adjust the
> publishing rate, in my case with 10,000 messages per second and 2 clients the
> problem happens within a couple of minutes.
> I also found a workaround for this problem: as far as I can understand, my
> original message is copied as a Java object to the broker (the broker is
> embedded, so there is no need to serialize it), then it is copied using its
> copy method to one or more new ActiveMQMessage instances and these are pushed
> into the consumer queues and then serialized to be sent over tcp.
> I think that under some particular conditions the properties are not
> serialized into the marshalledProperties field or this happens after the
> message has been actually sent.
> My workaround is to force the marshalling of properties into the
> marshalledProperties field when the message is copied using the copy method.
> This is not very clean, but still acceptable. The problem is that, in order
> for this to work, I need to create messages of a subclass of
> ActiveMqBytesMessage using an explicit constructor call rather that
> session.createBytesMessage() and I need to set the connection into them.
> Here is the code of my redefined class (this is the BytesMessage version, but
> the same is applicable to other kinds of messages):
> {noformat}
> import java.io.DataOutputStream;
> import java.io.IOException;
> import javax.jms.Session;
> import org.apache.activemq.ActiveMQSession;
> import org.apache.activemq.command.ActiveMQBytesMessage;
> import org.apache.activemq.command.Message;
> import org.apache.activemq.util.ByteArrayOutputStream;
> import org.apache.activemq.util.MarshallingSupport;
> public class EarlySerializingBytesMessage extends ActiveMQBytesMessage
> {
> private static final org.apache.log4j.Logger logger =
> org.apache.log4j.Logger.getLogger(EarlySerializingBytesMessage.class);
>
> public EarlySerializingBytesMessage(Session session)
> {
> ActiveMQSession activeMqSession = (ActiveMQSession)session;
> setConnection(activeMqSession.getConnection());
> }
>
> /*
> * We redefine <code>copy</code> to force the marshalling of properties
> here and avoid a problem we've found with serialized properties
> * arriving empty on the client side.
> * This is a workaround to make sure the properties are already
> serialized when ActiveMQ actually sends the message to
> * the client.
> * This happens very rarely and it is very difficult to spot this error
> in a "normal" testing session.
> * To have reasonable changes to reproduce it, we use a stress test tool
> that sends 5000 messages a second and at that rate
> * the error happens usually within 10 minutes, so we can say that one
> message every million is typically affected.
> * The actual problem is probably due to a bug in the ActiveMQ broker.
> Basically, it serializes every message just before
> * sending it and it happens that the marshalled properties are missing
> the resulting message, so we get an error on the client
> * as soon as we try to read them.
> * Since we use an embedded broker, our original message is never
> serialized, it is passed into the publishing queue as a Java object,
> * then it is copied into a new message of the same base type
> (ActiveMQBytesMessage, in this case) and pushed into the subscribers'
> * queues (a topic is actually implemented as a series of queues, one for
> each subscriber). In order to do this, the <code>copy</code>
> * method is invoked, we redefine it to early serialize the properties
> and make sure that this step is not skipped.
> */
> @Override
> public Message copy()
> {
> try
> {
> ByteArrayOutputStream baos = new ByteArrayOutputStream();
> DataOutputStream os = new DataOutputStream(baos);
> MarshallingSupport.marshalPrimitiveMap(properties, os);
> os.close();
> marshalledProperties = baos.toByteSequence();
> }
> catch(IOException exc)
> {
> logger.error("Error marhalling message properties, message was "
> + this, exc);
> }
>
> return super.copy();
> }
> }
> {noformat}
> The problem happens both on Java and C# clients, with the following
> stacktraces:
> Java:
> {noformat}
> javax.jms.JMSException: java.io.EOFException
> at
> org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62)
> at
> org.apache.activemq.filter.PropertyExpression.evaluate(PropertyExpression.java:199)
> at
> org.apache.activemq.command.ActiveMQMessage.getObjectProperty(ActiveMQMessage.java:509)
> at
> org.apache.activemq.command.ActiveMQMessage.getStringProperty(ActiveMQMessage.java:604)
> at
> activemq.emptypropertiestest.Subscriber$1.onMessage(Subscriber.java:65)
> at
> org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1230)
> at
> org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:134)
> at
> org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:205)
> at
> org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:127)
> at
> org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:619)
> Caused by: java.io.EOFException
> at java.io.DataInputStream.readInt(DataInputStream.java:375)
> at
> org.apache.activemq.util.MarshallingSupport.unmarshalPrimitiveMap(MarshallingSupport.java:83)
> at
> org.apache.activemq.util.MarshallingSupport.unmarshalPrimitiveMap(MarshallingSupport.java:73)
> at
> org.apache.activemq.command.Message.unmarsallProperties(Message.java:202)
> at org.apache.activemq.command.Message.getProperty(Message.java:159)
> at
> org.apache.activemq.filter.PropertyExpression.evaluate(PropertyExpression.java:197)
> ... 11 more
> {noformat}
> C#:
> {noformat}
> System.IO.EndOfStreamException: Unable to read beyond the end of the stream.
> at System.IO.MemoryStream.InternalReadInt32()
> at System.IO.BinaryReader.ReadInt32()
> at Apache.NMS.Util.EndianBinaryReader.ReadInt32()
> at Apache.NMS.Util.PrimitiveMap.UnmarshalPrimitiveMap(BinaryReader dataIn)
> at Apache.NMS.Util.PrimitiveMap.UnmarshalPrimitiveMap(Byte[] data)
> at Apache.NMS.Util.PrimitiveMap.Unmarshal(Byte[] data)
> at Apache.NMS.ActiveMQ.Commands.ActiveMQMessage.get_Properties()
> ...
> {noformat}
--
This message was sent by Atlassian JIRA
(v6.1#6144)