Attempting to deserialize user-created objects doesn't work when ActiveMQ is 
deployed in an OSGi container (e.g. ServiceMix 4)
------------------------------------------------------------------------------------------------------------------------------

                 Key: AMQ-2392
                 URL: https://issues.apache.org/activemq/browse/AMQ-2392
             Project: ActiveMQ
          Issue Type: Bug
          Components: Broker
    Affects Versions: 5.3.0
         Environment: Apache ServiceMix 4 (FUSE ESB 4.1.0.2)
Apache ActiveMQ 5.3.0.3 (embedded in FUSE ESB)
Apache Camel 1.6.1 (embedded in FUSE ESB)
            Reporter: Scott Parkerson


I am attempting to use the POJO sending and producing patterns as described. 
Here is my setup:

In one class (a CXF-based RESTful webservice), I have the following set
up:

{noformat}
    // OutboundFooRequestHandler is an interface (see below)
    @Produce(uri="activemq:queue:outbound_foo_req")
    private OutboundFooRequestHandler   outboundFooRequestHandler;

    @POST
    @Path("/sendfoo")
    public Response sendFoo(OutboundFooRequest sendFooRequest)
    {        
        // (a bunch of web-specific code deleted)

        // send this sendFooReqest object on the queue    
        outboundFooRequestHandler.handle(sendFooRequest);
       
        // Return HTTP response 202 Accepted
        return Response.status(202).build();
    }

{noformat}


The interface that is annotated with {...@produce}} is shown below:

{noformat}
@InOnly
public interface OutboundFooRequestHandler
{
    public void handle(OutboundFooRequest outboundFooRequest);    
}
{noformat}

Here is the implementation of the interface:

{noformat}
    public class OutboundFooRequestHandlerImpl implements
        OutboundFooRequestHandler, InitializingBean, DisposableBean
    {

    private static final Logger logger =
        LoggerFactory.getLogger(OutboundFooRequestHandlerImpl.class);

    @Override
    @Consume(uri="activemq:queue:outbound_foo_req")
    public void handle(@Body OutboundFooRequest outboundFooRequest)
    {
        logger.debug("got it");
       
        // TODO: actually *do* something
    }

{noformat}

The producer's {{bundle-context.xml}} looks like this:

{noformat}
    <camelContext
          xmlns="http://activemq.apache.org/camel/schema/spring"; />
   
    <bean name="activemq"
          class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="vm://default" />
            </bean>
        </property>
    </bean>
{noformat}

And the consumer's {{bundle-context.xml}} looks the same, except I'm 
instantiating my Impl classes.

When I attempt to send a message through the system, the producer produces a 
{{BeanInvocation}} object wrapping the {{SendFooRequest}} object.  However, the 
consumer thread barfs with this stacktrace:

{noformat}
4:20:24,843 | WARN  | nerContainer-195 | DefaultMessageListenerContainer  | 
AbstractMessageListenerContainer  646 | 
Execution of JMS message listener failed
org.apache.camel.RuntimeCamelException: 
org.apache.camel.component.jms.RuntimeJmsException: 
Failed to extract body due to: javax.jms.JMSException: Failed to build body 
from content. Serializable class not 
available to broker. Reason: java.lang.ClassNotFoundException: 
org.apache.camel.component.bean.BeanInvocation. 
Message: ActiveMQObjectMessage {commandId = 5, responseRequired = true, 
messageId = ID:xyzzy.ateb.com-55483-1252952224263-2:5:1:1:1, 
originalDestination = null, originalTransactionId = null, producerId = 
ID:xyzzy.ateb.com-55483-1252952224263-2:5:1:1, 
destination = queue://outbound_sms_req, transactionId = null, expiration = 0, 
timestamp = 1252952424801, arrival = 0, 
brokerInTime = 1252952424802, brokerOutTime = 1252952424822, correlationId = 
null, replyTo = null, persistent = true, 
type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId 
= null, compressed = false, userID = null, 
content = org.apache.activemq.util.byteseque...@141bf9f, marshalledProperties = 
null, dataStructure = null, 
redeliveryCounter = 0, size = 1718, properties = null, readOnlyProperties = 
true, readOnlyBody = true, droppable = false}
        at 
org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:850)
        at 
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:95)
        at 
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543)
        at 
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482)
        at 
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451)
        at 
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323)
        at 
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261)
        at 
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
        at 
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:881)
        at java.lang.Thread.run(Thread.java:636)
Caused by: org.apache.camel.component.jms.RuntimeJmsException: Failed to 
extract body due to: javax.jms.JMSException: 
Failed to build body from content. Serializable class not available to broker. 
Reason: java.lang.ClassNotFoundException: 
org.apache.camel.component.bean.BeanInvocation. Message: ActiveMQObjectMessage 
{commandId = 5, 
responseRequired = true, messageId = 
ID:xyzzy.ateb.com-55483-1252952224263-2:5:1:1:1, originalDestination = null, 
originalTransactionId = null, producerId = 
ID:xyzzy.ateb.com-55483-1252952224263-2:5:1:1, destination = 
queue://outbound_sms_req,
 transactionId = null, expiration = 0, timestamp = 1252952424801, arrival = 0, 
brokerInTime = 1252952424802, brokerOutTime = 1252952424822,
 correlationId = null, replyTo = null, persistent = true, type = null, priority 
= 4, groupID = null, groupSequence = 0, targetConsumerId = null, 
compressed = false, userID = null, content = 
org.apache.activemq.util.byteseque...@141bf9f, marshalledProperties = null, 
dataStructure = null, redeliveryCounter = 0, size = 1718, properties = null, 
readOnlyProperties = true, readOnlyBody = true, droppable = false}
        at 
org.apache.camel.component.jms.JmsBinding.extractBodyFromJms(JmsBinding.java:105)
        at 
org.apache.camel.component.jms.JmsMessage.createBody(JmsMessage.java:168)
        at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:45)
        at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:52)
        at 
org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:90)
        at 
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:72)
        ... 8 more
Caused by: javax.jms.JMSException: Failed to build body from content. 
Serializable class not available to broker. Reason: 
java.lang.ClassNotFoundException: org.apache.camel.component.bean.BeanInvocation
        at 
org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:35)
        at 
org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:179)
        at 
org.apache.camel.component.jms.JmsBinding.extractBodyFromJms(JmsBinding.java:91)
        ... 13 more
Caused by: java.lang.ClassNotFoundException: 
org.apache.camel.component.bean.BeanInvocation
        at 
org.apache.felix.framework.searchpolicy.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:558)
        at 
org.apache.felix.framework.searchpolicy.ModuleImpl.access$100(ModuleImpl.java:59)
        at 
org.apache.felix.framework.searchpolicy.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1427)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at 
org.apache.activemq.util.ClassLoadingAwareObjectInputStream.load(ClassLoadingAwareObjectInputStream.java:63)
        at 
org.apache.activemq.util.ClassLoadingAwareObjectInputStream.resolveClass(ClassLoadingAwareObjectInputStream.java:37)
        at 
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1592)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
        at 
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
        at 
org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:177)
        ... 14 more
{noformat}

A couple of relevant conversations on IRC. First, from {{#camel}}:
{quote}
<smerp> I don't suppose anyone would know what I need to do to the ActiveMQ 
broker to pass BeanInvocation messages?
<-- mr_smith has quit (Ping timeout)
<smerp> Using @Consume, I'm getting Failed to extract
 body due to: javax.jms.JMSException: Failed to build body from content.
 Serializable class not available to broker. Reason:
 java.lang.ClassNotFoundException:
 org.apache.camel.component.bean.BeanInvocation
<cibsen> BeanInvocation is a internal camel class that is like meta data about 
some bean to invoke
 are you sure you want to route that?
 chirino ccustine cibsen
<smerp> cibsen: Well, I was just following the examples for @Produce and 
@Consume in the online docs
<smerp> cibsen: more background was posted on the camel-users mailing list. 
Here's a URL to the current thread: 
http://www.nabble.com/Using-%40Produce---%40Consume----What-am-I-missing--tt25437492.html
<cibsen> well you use OSGi then you got all the pain it brings along :(
smerp plays sadtrombone.wav
<smerp> :|
<cibsen> eg activemq.jar wants to deserialize the object it received over JMS 
but OSGi forbids it to see the org.apache.camel classes
 as its not importing them

{quote}

...and then a later one on {{#servicemix}}:
{quote}
<smerp> Can any SMX folks tell me what to do to get ActiveMQ embedded in SMX to 
"see" the camel classes (BeanInvocation, specifically)
 OSGi, as awesome as it is, is a pain sometimes.
 Context is here -> 
http://www.nabble.com/Using-%40Produce---%40Consume----What-am-I-missing--tt25437492.html
 (see the last post)
<ccustine> smerp: I fear this would require a DynamicImport-Package in the 
ActiveMQ bundle
<smerp> ccustine: :(
 ccustine: is this a bug? or a feature? or perhaps a fug?
<ccustine> smerp: the correct option is probably to modify AMQ 
ClassLoadingAwareObjectInputStream to be more OSGi aware
<smerp> crap.
<ccustine> smerp: probably fug  :-/
<smerp> ccustine: any decent workarounds for now?
 ccustine: I'll file a JIRA for it
 Probably needs to be on ActiveMQ, right?
<ccustine> DynamicImport on AMQ is the fastest, but may have unanticipated 
problems
 well... good question
 probably, but officially there isn't much OSGi specific in AMQ
 this is getting kinda specific, but you can start there
 I think this is something we need to figure out
 so basically it sounds like any objectmessage that is serialized from a user 
type will have this occur
<smerp> right... this is a tricky problem, as the problem is (a) caused by 
something that is recommended in Camel (BeanInvocations on queues) and (b) is 
broken only when using ActiveMQ in SMX 4 w/OSGi
<ccustine> right
<smerp> I think so -- it happens the object type is from Camel, but yes
<ccustine> seems like a general use case that is broken in OSGi, so I would 
open the bug under AMQ and then we will work with them to figure out a solution
 chirino ccustine
<smerp> ccustine: Alright, sounds good
smerp goes to JIRA
<ccustine> smerp: I may have a nasty workaround by modifying the activemq.xml 
that we deploy in SMX....
<smerp> ccustine: that would be great for the short term -- it would get me 
moving again
 (if it works)
<ccustine> open the bug and I will look at this hack for a bit
 yeah
{quote}

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

Reply via email to