Incorporating Remoting http transport into Messaging
ron_sigal Sep 21, 2006 3:18 AMI'm starting this thread to discuss the integration of the JBossRemoting http transport into messaging. With some changes to Messaging code and some changes to Remoting code the test org.jboss.example.jms.http.HttpExample passes.
The Messaging changes revolve around JMSWireFormat:
1. JMSWireFormat can't expect to get passed ObjectInputStreams and ObjectOutputStreams. This has been discussed already, although I can't find the reference. I changed it to create object streams as necessary. However, when they are created, e.g.,
oos = SerializationStreamFactory.getManagerInstance("key").createOutput(out);
"key" has to be replaced by a suitable value. I assume it would be acceptable to just hard code "jboss", but the solution to problem 2) below involves passing in the server's InvokerLocator, so it's easy to do a quick check for any specific instructions about serialization. By the way, I see that in ServerPeer, the key "jms" is associated with jboss serialization, but I don't see any use of "jms" anywhere, so I commented that out. Since ServerPeer doesn't currently have access to the InvokerLocator, I also commented out the registration of a JMSWireFormat keyed on "jms".
2. JMS uses instances of SerializableMarshaller and SerializableUnMarshaller in some default cases. However, the http transport needs to use subclasses HTTPMarshaller and HTTPUnMarshaller, which means JMSWireFormat needs to know what transport is being used. An easy way to determine the transport would be to look at the InvokerLocator, but currently the InvokerLocator doesn't seem to be available everywhere it would be needed. Instances of JMSWireFormat are created in the following classes:
JMSRemotingConnection - no problem: it has the InvokerLocator
ClientConnectionFactoryDelegate - no problem: it already gets the InvokerLocator
ServerConnectionEndpoint - I changed the constructor so that ServerConnectionFactoryEndpoint can pass in the InvokerLocator
TestWireFormat - it calls the JMSWireFormat default constructor, which defaults to the socket transport and jboss serialization
It was also necessary to change the ServerConnectionFactoryEndpoint constructor to pass in the InvokerLocator, so it could pass it to ServerConnectionEndpoint.
3. A third change was necessary in JMSWireFormat, due to the way the server side http invoker (CoyoteInvoker) returns invocation results. In particular, since it doesn't know if it's talking to the client side http invoker or some other foreign client, it can't necessarily return the result wrapped in an InvocationResponse. We made some changes to the http transport so that the client side can tell the server side that it's a remoting invoker, but that involves putting a flag in the InvocationRequest. Since JMSWireFormat doesn't wrap messaging messages in an InvocationRequest, the changes don't help JMSWireFormat in general (though it solves a problem with null responses from internal Remoting requests). So, I changed the decision tree in JMSWireFormat.write() to accept arbitrary objects.
4. The http transport needs tomcat jars.