[ https://issues.apache.org/jira/browse/CAMEL-3449?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12976230#action_12976230 ]
Claus Ibsen commented on CAMEL-3449: ------------------------------------ This wont work with classloading as its much more complicated in JEE servers, OSGi and whatnot. You need to use the {{ClassResolver}} from {{CamelContext}} to load a given class. Can you see if you can refine the patch to leverage this? > 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: Future > > 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.