[
https://issues.apache.org/jira/browse/CAMEL-3449?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Caspar MacRae updated CAMEL-3449:
---------------------------------
Attachment: camel-core.patch
camel-core patch for MethodBean
> Change to allow proxying (of non-serializable beans) to work over protocols
> such as Mina/Netty
> ----------------------------------------------------------------------------------------------
>
> Key: CAMEL-3449
> URL: https://issues.apache.org/jira/browse/CAMEL-3449
> Project: Camel
> Issue Type: Improvement
> Components: camel-core
> Affects Versions: 2.5.0
> Reporter: Caspar MacRae
> Priority: Minor
> Fix For: 2.6.0
>
> Attachments: camel-core.patch
>
>
> Hi,
> Hiding middleware with proxying of Pojos with transports such as JMS, or
> "direct: ..." is fantastically simple. However problems arise using
> Mina/Netty - there appears to be an issue with the default serializing codecs
> for these in that they cannot resolve the declaring class correctly from
> MethodBean used in BeanInvocation.
> I've looked at the documentation and am reasonably confident that it's not a
> configuration issue, but please enlighten me if it's so.
> Not spent long enough on this to understand why this happens - Class.java is
> Serializable and as the MethodBean is sending a definition not an instance it
> shouldn't matter whether the target pojo implements Serializable at all? The
> exceptions thrown are fairly cryptic, NullPointers from the bowels of Object
> stream deserialization etc.
> Anyway, by changing the MethodBean's internal rep to use the class' canonical
> name it's possible to enjoy painless proxying over these transports. This
> doesn't break any existing tests but there may be side effects of loading the
> class on the receiving side (not tested in OSGi or Spring envs).
> Also (issue for upstream project) Mina cannot resolve inner classes properly
> (uses dot not dollar).
> Some test code:
> ---------------------------------------------------------------------------------------------------------------------
> import java.io.Serializable;
> public interface HelloSerializableService extends HelloService, Serializable
> {}
> ---------------------------------------------------------------------------------------------------------------------
> public class HelloSerializableServiceImp implements HelloSerializableService {
> private static final long serialVersionUID = 1112126394143803848L;
> public String sayHelloTo(String who) {
> return "Hello " + who;
> }
> }
> ---------------------------------------------------------------------------------------------------------------------
> public interface HelloService {
> public String sayHelloTo(String who);
> }
> ---------------------------------------------------------------------------------------------------------------------
> public class HelloServiceImp implements HelloService {
> public String sayHelloTo(String who) {
> return "Hello " + who;
> }
> }
> ---------------------------------------------------------------------------------------------------------------------
> public class MethodBeanClassAsStringTest extends CamelTestSupport {
> public static final String DIRECT_TO_NONSERIAL = "direct:nonserial";
> public static final String MINA_TO_NONSERIAL =
> "mina:tcp://0.0.0.0:6060?sync=true&allowDefaultCodec=true";
> public static final String MINA_TO_SERIAL =
> "mina:tcp://0.0.0.0:6065?sync=true&allowDefaultCodec=true";
> public MethodBeanClassAsStringTest() {
> setUseRouteBuilder(true);
> }
> @Override
> protected RouteBuilder createRouteBuilder() throws Exception {
> return new RouteBuilder() {
> final HelloService service = new HelloServiceImp();
> final HelloSerializableService serialService = new
> HelloSerializableServiceImp();
> @Override
> public void configure() throws Exception {
> from(DIRECT_TO_NONSERIAL).bean(service);
> from(MINA_TO_NONSERIAL).bean(service);
> from(MINA_TO_SERIAL).bean(serialService);
> }
> };
> }
>
> @Test
> public void testDirectNonserial() throws Exception {
> Endpoint endpoint = context.getEndpoint(DIRECT_TO_NONSERIAL);
> HelloService service = createProxy(endpoint,
> getClass().getClassLoader(), new Class<?>[]{ HelloService.class});
> String response = service.sayHelloTo("Camel");
> assertEquals("Hello Camel", response);
> }
> @Test
> public void testMinaNonserial() throws Exception {
> Endpoint endpoint = context.getEndpoint(MINA_TO_NONSERIAL);
> HelloService service = createProxy(endpoint,
> getClass().getClassLoader(), new Class<?>[]{ HelloService.class});
> String response = service.sayHelloTo("Camel");
> assertEquals("Hello Camel", response);
> }
> @Test
> public void testMinaSerial() throws Exception {
> Endpoint endpoint = context.getEndpoint(MINA_TO_SERIAL);
> HelloSerializableService service = createProxy(endpoint,
> getClass().getClassLoader(), new Class<?>[]{ HelloSerializableService.class});
> String response = service.sayHelloTo("Camel");
> assertEquals("Hello Camel", response);
> }
> // https://issues.apache.org/activemq/browse/CAMEL-3341 fixed in
> 2.6-SNAPSHOT
> public static <T> T createProxy(Endpoint endpoint, ClassLoader cl,
> Class<?>[] interfaces) throws Exception {
> Producer producer = endpoint.createProducer();
> ServiceHelper.startService(producer);
> CamelInvocationHandler invocationHandler = new
> CamelInvocationHandler(endpoint, producer, new
> MethodInfoCache(endpoint.getCamelContext()));
> @SuppressWarnings("unchecked")
> T retVal = (T) Proxy.newProxyInstance(cl, interfaces,
> invocationHandler);
> return retVal;
> }
>
> }
> ---------------------------------------------------------------------------------------------------------------------
> Exceptions from running the test without the patch:
> Sending side:
> java.lang.reflect.UndeclaredThrowableException
> at $Proxy9.sayHelloTo(Unknown Source)
> at
> net.earcam.camelproxy.MethodBeanClassAsStringTest.testMinaNonserial(MethodBeanClassAsStringTest.java:56)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
> at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
> at
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
> at
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
> at
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
> at
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
> at
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
> at
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.camel.CamelExchangeException: No response received from
> remote server: mina://tcp://0.0.0.0:6060?allowDefaultCodec=true&sync=true.
> Exchange[Message: BeanInvocation public abstract java.lang.String
> net.earcam.camelproxy.HelloService.sayHelloTo(java.lang.String) with [Camel]]]
> at
> org.apache.camel.component.mina.MinaProducer.process(MinaProducer.java:133)
> at
> org.apache.camel.component.bean.CamelInvocationHandler.invoke(CamelInvocationHandler.java:65)
> ... 26 more
> Recieving side:
> 837 [Camel Thread 21 - MinaThreadPool] WARN
> org.apache.camel.component.mina.MinaConsumer$ReceiveHandler -
> [/127.0.1.1:38374] Unexpected exception from exceptionCaught handler.
> org.apache.camel.CamelException:
> org.apache.mina.filter.codec.ProtocolDecoderException:
> java.lang.NullPointerException (Hexdump: 00 00 00 FB AC ED 00 05 73 72 01 00
> 2E 6F 72 67 2E 61 70 61 63 68 65 2E 63 61 6D 65 6C 2E 63 6F 6D 70 6F 6E 65 6E
> 74 2E 62 65 61 6E 2E 42 65 61 6E 49 6E 76 6F 63 61 74 69 6F 6E 78 70 73 72 01
> 00 2A 6F 72 67 2E 61 70 61 63 68 65 2E 63 61 6D 65 6C 2E 63 6F 6D 70 6F 6E 65
> 6E 74 2E 62 65 61 6E 2E 4D 65 74 68 6F 64 42 65 61 6E 78 70 74 00 0A 73 61 79
> 48 65 6C 6C 6F 54 6F 75 72 01 00 12 5B 4C 6A 61 76 61 2E 6C 61 6E 67 2E 43 6C
> 61 73 73 3B 78 70 00 00 00 01 76 72 01 00 10 6A 61 76 61 2E 6C 61 6E 67 2E 53
> 74 72 69 6E 67 78 70 76 72 01 00 22 6E 65 74 2E 65 61 72 63 61 6D 2E 63 61 6D
> 65 6C 70 72 6F 78 79 2E 48 65 6C 6C 6F 53 65 72 76 69 63 65 78 70 75 72 01 00
> 13 5B 4C 6A 61 76 61 2E 6C 61 6E 67 2E 4F 62 6A 65 63 74 3B 78 70 00 00 00 01
> 74 00 05 43 61 6D 65 6C 78)
> at
> org.apache.camel.component.mina.MinaConsumer$ReceiveHandler.exceptionCaught(MinaConsumer.java:92)
> at
> org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.exceptionCaught(AbstractIoFilterChain.java:564)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.callNextExceptionCaught(AbstractIoFilterChain.java:345)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.access$1000(AbstractIoFilterChain.java:53)
> at
> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.exceptionCaught(AbstractIoFilterChain.java:643)
> at
> org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:224)
> at
> org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:264)
> 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:662)
> Caused by: org.apache.mina.filter.codec.ProtocolDecoderException:
> java.lang.NullPointerException (Hexdump: 00 00 00 FB AC ED 00 05 73 72 01 00
> 2E 6F 72 67 2E 61 70 61 63 68 65 2E 63 61 6D 65 6C 2E 63 6F 6D 70 6F 6E 65 6E
> 74 2E 62 65 61 6E 2E 42 65 61 6E 49 6E 76 6F 63 61 74 69 6F 6E 78 70 73 72 01
> 00 2A 6F 72 67 2E 61 70 61 63 68 65 2E 63 61 6D 65 6C 2E 63 6F 6D 70 6F 6E 65
> 6E 74 2E 62 65 61 6E 2E 4D 65 74 68 6F 64 42 65 61 6E 78 70 74 00 0A 73 61 79
> 48 65 6C 6C 6F 54 6F 75 72 01 00 12 5B 4C 6A 61 76 61 2E 6C 61 6E 67 2E 43 6C
> 61 73 73 3B 78 70 00 00 00 01 76 72 01 00 10 6A 61 76 61 2E 6C 61 6E 67 2E 53
> 74 72 69 6E 67 78 70 76 72 01 00 22 6E 65 74 2E 65 61 72 63 61 6D 2E 63 61 6D
> 65 6C 70 72 6F 78 79 2E 48 65 6C 6C 6F 53 65 72 76 69 63 65 78 70 75 72 01 00
> 13 5B 4C 6A 61 76 61 2E 6C 61 6E 67 2E 4F 62 6A 65 63 74 3B 78 70 00 00 00 01
> 74 00 05 43 61 6D 65 6C 78)
> at
> org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:165)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
> at
> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
> at
> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:499)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
> at
> org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:293)
> at
> org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:228)
> at
> org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:198)
> at
> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$400(SocketIoProcessor.java:45)
> at
> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:485)
> at
> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
> ... 3 more
> Caused by: java.lang.NullPointerException
> at
> org.apache.mina.common.ByteBuffer$3.resolveClass(ByteBuffer.java:1529)
> at
> java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
> at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
> at java.io.ObjectInputStream.readClass(ObjectInputStream.java:1461)
> at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1311)
> at
> java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
> at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
> at
> java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
> at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
> at
> org.apache.camel.component.bean.BeanInvocation.readExternal(BeanInvocation.java:99)
> at
> java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791)
> at
> java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
> at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
> at org.apache.mina.common.ByteBuffer.getObject(ByteBuffer.java:1537)
> at
> org.apache.mina.filter.codec.serialization.ObjectSerializationDecoder.doDecode(ObjectSerializationDecoder.java:92)
> at
> org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:133)
> at
> org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:158)
> ... 14 more
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.