micronaut-projects / micronaut-jms

Integration between Micronaut and JMS
Apache License 2.0
14 stars 14 forks source link

Native Image CLI application cannot send message to AMQ broker #109

Closed tylervz closed 2 years ago

tylervz commented 3 years ago

Task List

Steps to Reproduce

In the root directory of my example project, run the following commands

  1. docker-compose up to run an AMQ broker.
  2. ./gradlew nativeImage (in a separate terminal) to build a native image of the application.
  3. ./build/native-image/application -v to run the CLI application and have it send a message to the broker.

Expected Behaviour

A message should be sent to the AMQ broker. It works fine when running the application with the JVM (java -jar build/libs/amq-jms-example-0.1-all.jar -v), however it throws an exception when running the Native Image.

Actual Behaviour

The following error stacktrace is output when ./build/native-image/application -v is executed

io.micronaut.messaging.exceptions.MessagingClientException: Problem sending message to example-messages
        at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:93)
        at io.micronaut.jms.configuration.JMSProducerMethodInterceptor.intercept(JMSProducerMethodInterceptor.java:117)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:96)
        at amq.jms.example.producer.StringMessageProducer$Intercepted.send(Unknown Source)
        at amq.jms.example.AmqJmsExampleCommand.run(AmqJmsExampleCommand.java:40)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
        at picocli.CommandLine.access$1300(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2352)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2346)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2311)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
        at picocli.CommandLine.execute(CommandLine.java:2078)
        at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:137)
        at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:114)
        at amq.jms.example.AmqJmsExampleCommand.main(AmqJmsExampleCommand.java:29)
Caused by: io.micronaut.messaging.exceptions.MessagingSystemException: Problem creating pooled Connection
        at io.micronaut.jms.pool.JMSConnectionPool.doCreate(JMSConnectionPool.java:53)
        at io.micronaut.jms.pool.JMSConnectionPool.create(JMSConnectionPool.java:59)
        at io.micronaut.jms.pool.JMSConnectionPool.create(JMSConnectionPool.java:33)
        at io.micronaut.jms.pool.AbstractPool.request(AbstractPool.java:58)
        at io.micronaut.jms.pool.JMSConnectionPool.createConnection(JMSConnectionPool.java:73)
        at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:88)
        ... 14 more
Caused by: javax.jms.JMSException: Disposed due to prior exception
        at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:54)
        at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1403)
        at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1486)
        at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:527)
        at io.micronaut.jms.pool.JMSConnectionPool.doCreate(JMSConnectionPool.java:50)
        ... 19 more
Caused by: org.apache.activemq.transport.TransportDisposedIOException: Disposed due to prior exception
        at org.apache.activemq.transport.ResponseCorrelator.onException(ResponseCorrelator.java:125)
        at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:114)
        at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:114)
        at org.apache.activemq.transport.WireFormatNegotiator.onException(WireFormatNegotiator.java:173)
        at org.apache.activemq.transport.WireFormatNegotiator.negociate(WireFormatNegotiator.java:161)
        at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:123)
        at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:301)
        at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
        at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
        at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
        at java.lang.Thread.run(Thread.java:829)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:553)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:192)
Caused by: java.io.IOException: Invalid version: 10, could not load org.apache.activemq.openwire.v10.MarshallerFactory
        at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:46)
        ... 9 more
Caused by: java.lang.IllegalArgumentException: Invalid version: 10, could not load org.apache.activemq.openwire.v10.MarshallerFactory
        at org.apache.activemq.openwire.OpenWireFormat.setVersion(OpenWireFormat.java:335)
        at org.apache.activemq.openwire.OpenWireFormat.renegotiateWireFormat(OpenWireFormat.java:614)
        at org.apache.activemq.transport.WireFormatNegotiator.negociate(WireFormatNegotiator.java:145)
        ... 8 more
Caused by: java.lang.ClassNotFoundException: org.apache.activemq.openwire.v10.MarshallerFactory
        at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:64)
        at java.lang.Class.forName(DynamicHub.java:1308)
        at org.apache.activemq.openwire.OpenWireFormat.setVersion(OpenWireFormat.java:333)
        ... 10 more

Environment Information

Example Application

https://github.com/tylervz/amq-jms-example

elliottpope commented 3 years ago

Hi @tylervz. My guess is this is an issue with the activemq-broker dependency. Could you try adding @TypeHint([org.apache.activemq.openwire.v10.MarshallerFactory]) in your project and seeing if that resolves this specific issue?

tylervz commented 3 years ago

Hi @elliottpope thanks for the suggestion. I'm a beginner with Micronaut so I'm not sure which class to decorate with @TypeHint. Because my project is a Picocli application, I added it above my main command class.

After adding the annotation @TypeHint([org.apache.activemq.openwire.v10.MarshallerFactory]) above my AmqJmsExampleCommand class definition, I'm unable to build the project:

error: illegal start of expression
@TypeHint([org.apache.activemq.openwire.v10.MarshallerFactory])
          ^
ilopmar commented 3 years ago

For Java you need to use {org.apache.....} instead of [...]

tylervz commented 3 years ago

Thanks @ilopmar

Now I'm getting the following error when I try to build the project:

amq-jms-example/src/main/java/amq/jms/example/AmqJmsExampleCommand.java:19: error: cannot find symbol
@TypeHint({org.apache.activemq.openwire.v10.MarshallerFactory})
                                       ^
  symbol:   class v10
  location: package org.apache.activemq.openwire
elliottpope commented 3 years ago

@tylervz my bad, I fired off the comment without actually writing valid Java code. The valid syntax for you is

@TypeHint({
    org.apache.activemq.openwire.v10.MarshallerFactory.class
})

and yes you can place this as a class-level annotation on your AmqJmsExampleCommand class. I'm just verifying on my machine whether this actually solves your problem, but this is what I would expect to solve the problem

elliottpope commented 3 years ago

Ok, sorry this was a little late but my laptop is not powerful enough to run the native image compile.

@TypeHint(
   value = { org.apache.activemq.openwire.v10.MarshallerFactory.class }, 
   accessType = AccessType.ALL_DECLARED_METHODS)

will solve you're problem. I have tested it out on my machine and everything is working perfectly. Sample log output after build/native-image/application -v is:

08:56:43.262 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [cli]
About to send this message to the queue: 2b2c6320-316b-4949-93b1-004a99d46b17
Queue name: example-messages
Sent message: 2b2c6320-316b-4949-93b1-004a99d46b17
elliottpope commented 3 years ago

@tylervz if this resolves you're issue then I can close this ticket for you.

@graemerocher if I add

@TypeHint(
   value = { org.apache.activemq.openwire.v10.MarshallerFactory.class }, 
   accessType = AccessType.ALL_DECLARED_METHODS)

to the micronaut-jms-activemq-classic project, will all downstream projects not require this change? What I'm basically asking is whether the @TypeHint annotations cascade through dependencies

graemerocher commented 3 years ago

Yes adding that to one of the classes and ensure the annotationProcessor "io.micronaut:micronaut-graal" is present in the dependencies will result in resolving the issue and it cascading to downstream projects

elliottpope commented 3 years ago

Thank you, I will add this to the project close this ticket with that PR

tylervz commented 3 years ago

@elliottpope sorry for my unresponsiveness; I was on vacation and just got back.

@TypeHint(
   value = { org.apache.activemq.openwire.v10.MarshallerFactory.class }, 
   accessType = AccessType.ALL_DECLARED_METHODS)

Does indeed solve my problem. Thank you!