You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Ruben Martin (JIRA)" <ji...@apache.org> on 2009/05/06 12:14:39 UTC

[jira] Commented: (AMQ-2083) java.io.OptionalDataException when getting a deeply nested HashMap from an ObjectMessage

    [ https://issues.apache.org/activemq/browse/AMQ-2083?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=51532#action_51532 ] 

Ruben Martin commented on AMQ-2083:
-----------------------------------

We are facing the same problem. In our case, the first object is a custom object with some primitive fields and a map (HashMap). This map contains other deeply nested maps. We tried making the first map a synchronizedMap, but it did not work. And anyway both writer and reader are wraped on transactions (spring) and synchronized methods.
The strange thing is that we cannot reproduce the problem in a consistent way in our tests, it is somehow random (maybe related to the system load?)

Martin, could you please be a bit more explicit about the way you solved the problem with synchronization? Any hint will be much appreciated.

javax.jms.JMSException: Failed to build body from bytes. Reason: java.io.OptionalDataException
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:35)
	at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:183)
	at org.fundacionctic.tawmonitor.motor.service.GestorResultadosService.onMessage(GestorResultadosService.java:62)
	at sun.reflect.GeneratedMethodAccessor3031.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
	at $Proxy393.onMessage(Unknown Source)
	at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:531)
	at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:466)
	at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:435)
	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:316)
	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:235)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:887)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:815)
	at java.lang.Thread.run(Thread.java:619)
Caused by: java.io.OptionalDataException
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at java.util.LinkedList.readObject(LinkedList.java:964)
	at sun.reflect.GeneratedMethodAccessor2908.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at java.util.ArrayList.readObject(ArrayList.java:593)
	at sun.reflect.GeneratedMethodAccessor2939.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at java.util.ArrayList.readObject(ArrayList.java:593)
	at sun.reflect.GeneratedMethodAccessor2939.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at java.util.HashMap.readObject(HashMap.java:1030)
	at sun.reflect.GeneratedMethodAccessor2573.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:177)
	... 25 more

> java.io.OptionalDataException when getting a deeply nested HashMap from an ObjectMessage
> ----------------------------------------------------------------------------------------
>
>                 Key: AMQ-2083
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2083
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.2.0
>         Environment: JRE 1.5.0_12
>            Reporter: Martin Haslinger
>
> In rare occasions getting a HashMap from an ObjectMessage leads to the following error:
> javax.jms.JMSException: Failed to build body from bytes. Reason: java.io.OptionalDataException
> 	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:35)
> 	at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:183)
> Caused by: java.io.OptionalDataException
> 	at java.io.ObjectInputStream.readObject0(Unknown Source)
> 	at java.io.ObjectInputStream.readObject(Unknown Source)
> 	at java.util.HashMap.readObject(Unknown Source)
> 	at sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> 	at java.lang.reflect.Method.invoke(Unknown Source)
> 	at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
> 	at java.io.ObjectInputStream.readSerialData(Unknown Source)
> 	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
> 	at java.io.ObjectInputStream.readObject0(Unknown Source)
> 	at java.io.ObjectInputStream.readObject(Unknown Source)
> 	at java.util.HashMap.readObject(Unknown Source)
> 	at sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> 	at java.lang.reflect.Method.invoke(Unknown Source)
> 	at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
> 	at java.io.ObjectInputStream.readSerialData(Unknown Source)
> 	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
> 	at java.io.ObjectInputStream.readObject0(Unknown Source)
> 	at java.io.ObjectInputStream.readObject(Unknown Source)
> 	at java.util.HashMap.readObject(Unknown Source)
> 	at sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> 	at java.lang.reflect.Method.invoke(Unknown Source)
> 	at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
> 	at java.io.ObjectInputStream.readSerialData(Unknown Source)
> 	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
> 	at java.io.ObjectInputStream.readObject0(Unknown Source)
> 	at java.io.ObjectInputStream.readObject(Unknown Source)
> 	at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:177)
> 	... 8 more
> The only difference in the testing application to all other messages is that the object is a deeply nested map, it is: HashMap<String, HashMap<String, HashMap<String,String>>>
> Alltough the OptionalDataException indicates some primitive values being written somewhere, there are absolute no primitive values around there.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Re: [jira] Commented: (AMQ-2083) java.io.OptionalDataException when getting a deeply nested HashMap from an ObjectMessage

Posted by martinhasl <ma...@fh-vie.ac.at>.
I solved the problem by synchronizing every access to the map and by making a
deep copy of the map whenever it is revealed to the outside. Our real
problem was that the access to the map was already synchronized but it was
not copied deeply enough at a getter so it was possible that other classes
access sub-maps of the map while it was serialized by ActiveMQ.

Code which caused the problems:
public Map<String, Map<String, String> getMap()
{
  // here a new map is produced to ensure a new object is created and the
member-variable mymap can not be accessed directly from the outside
  // however the sub-maps of mymap still remain the same object and
therefore can be directly changed from the outside which should not be the
case
  return new HashMap(mymap);
}

Code that solved the problem (not the real code, just some idea):
public Map<String, Map<String, String> getMap()
{
  HashMap newmap = new HashMap();
  for(Entry<Map<String, String>> e : mymap.entrySet())
  {
    newmap.put(e.getKey(), new HashMap(e.getValue());
  }
  return newmap;
}

Maybe this helps you a bit. I think the reason why it is not reproducable
and only happens rarely is that it is a typical multithreading-problem and
only occurs if the map is accessed exactly while it is getting serialized by
ActiveMQ.

greetings,
Martin



JIRA jira@apache.org wrote:
> 
> 
>     [
> https://issues.apache.org/activemq/browse/AMQ-2083?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=51532#action_51532
> ] 
> 
> Ruben Martin commented on AMQ-2083:
> -----------------------------------
> 
> We are facing the same problem. In our case, the first object is a custom
> object with some primitive fields and a map (HashMap). This map contains
> other deeply nested maps. We tried making the first map a synchronizedMap,
> but it did not work. And anyway both writer and reader are wraped on
> transactions (spring) and synchronized methods.
> The strange thing is that we cannot reproduce the problem in a consistent
> way in our tests, it is somehow random (maybe related to the system load?)
> 
> Martin, could you please be a bit more explicit about the way you solved
> the problem with synchronization? Any hint will be much appreciated.
> 

-- 
View this message in context: http://www.nabble.com/-jira--Created%3A-%28AMQ-2083%29-java.io.OptionalDataException-when-getting-a-deeply-nested-HashMap-from-an-ObjectMessage-tp21580409p23424597.html
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.