Project: springxd
Issue XD-3264: Spring Data BytecodeGeneratingEntityInstantiator throws ClassNotFoundException when mapping custom classes
{{spring-data-commons}} 1.10.0.RELEASE introduced an improved instantiation strategy based on byte code generation. It's now the default instantiation strategy however it can't be used in custom Spring XD modules due to class loader issues. Please see attached custom module source code which can be build with Maven. You might want to change MongoDB connection parameters in {{custom-mongo-processor.xml}}. Execute following xd-shell commands {code} module upload --name custom-mongo-processor --type processor --file [location] stream create --name k2 --definition 'time --fixedDelay=10 | custom-mongo-processor | log' --deploy {code} The stream will output following message when the MongoDB collection is empty: {code} 2015-07-17T11:09:38+0100 1.2.0.RELEASE INFO task-scheduler-3 sink.k2 - {"content":[],"count":0} 2015-07-17T11:09:48+0100 1.2.0.RELEASE INFO task-scheduler-3 sink.k2 - {"content":[],"count":0} {code} After documents are inserted into collection by executing {{db.karolWidgets.insert(\{ "name": "bulbator", "color": "red" \})}} following exception will be thrown: {code} 2015-07-17T11:09:59+0100 1.2.0.RELEASE ERROR task-scheduler-3 handler.LoggingHandler - org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.IllegalStateException: Cannot process message org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78) org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71) org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99) org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:287) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231) org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154) org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102) org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105) org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:287) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231) org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154) org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102) org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105) org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:287) org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:130) org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:219) org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:55) org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:149) org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:146) org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:298) org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:52) org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:49) org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:292) org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) java.util.concurrent.FutureTask.run(FutureTask.java:262) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) java.lang.Thread.run(Thread.java:745) Caused by: java.lang.IllegalStateException: Cannot process message org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:292) org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:142) org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:75)	... 59 more Caused by: java.lang.NoClassDefFoundError: com/test/mongodb/MongoWidget com.test.mongodb.MongoWidget_Instantiator_monxdt.newInstance(Unknown Source) org.springframework.data.convert.BytecodeGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(BytecodeGeneratingEntityInstantiator.java:193) org.springframework.data.convert.BytecodeGeneratingEntityInstantiator.createInstance(BytecodeGeneratingEntityInstantiator.java:76) org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:250) org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231) org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:191) org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:187) org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78) org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2191) org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1873) org.springframework.data.mongodb.core.MongoTemplate.findAll(MongoTemplate.java:1286) com.test.mongodb.MongoService.processWidgets(MongoService.java:21) sun.reflect.GeneratedMethodAccessor83.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:606) org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112) org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:102) org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49) org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342) org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131) org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330) org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:164) org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:276)	... 61 more Caused by: java.lang.ClassNotFoundException: com.test.mongodb.MongoWidget java.lang.ClassLoader.findClass(ClassLoader.java:531) java.lang.ClassLoader.loadClass(ClassLoader.java:425) java.lang.ClassLoader.loadClass(ClassLoader.java:358)	... 85 more {code} This exception affects both custom stream and job modules. One workaround is to force {{ReflectionEntityInstantiator}} in {{MappingMongoConverter}} however this has to be done in every custom module. Perhaps that's an issue with Spring XD custom module classloaders (or DATACMNS-710)?
Story points: 3