1
votes

I'd like to create a setup to evaluate messaging with JMS. The target environment would be a normal Payara, yet to have a simple setup, I'd like to test things out with Payara Micro (bundled jar). This ways, I'd like to create a setup that can be ported easily. With JNDI lookups, there should be no problems with the code in this regard. Also, the coding part isn't really hard. Things I'd like to test with this setup: - Consumer using message driven beans - Producer - accessing management queue (as I'd like to test how to enable blue/green-deployment)

Using the rar of the classic ActiveMQ, things were comparebly easy. I set up a post-boot-commands.txt to deploy and config the resource adapter with the following content:


create-resource-adapter-config  --property ServerUrl='tcp://localhost:61616':UserName='admin':Password='admin' activemq-rar-5.15.11

create-connector-connection-pool  --raname activemq-rar-5.15.11 --connectiondefinition javax.jms.ConnectionFactory --ping true --isconnectvalidatereq true jms/myConnectionPool

create-connector-resource --poolname jms/myConnectionPool jms/myConnectionFactory

create-admin-object --raname activemq-rar-5.15.11 --restype javax.jms.Queue --property PhysicalName=Q1 jms/myQueue

This lets Payara Micro deploy and config the rar before deploying my apps war-file. The message driven bean could then be written with this configuration:

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "Q1"),
        @ActivationConfigProperty(propertyName = "resourceAdapter", propertyValue = "activemq-rar-5.15.11"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class MyMDB implements MessageListener {
   ...
}

As the Producer was easy, I'll skip that part here. Things worked well until I started to work with the management queue. Following the management example coming with the broker (which uses some deprecated code :(), I ran into conflicts as the solution used code from the artemis client which then conflicted with the ConnectionFactory classes from the classic ActiveMQ rar. As I have a bad feeling using the classic ActiveMQs rar with ActiveMQ Artemis, I tried to switch to the artemis rar. Unfortunately, finding information about how to config the resource adapter with Payara means turned out to be hell on earth.

By taking a look at the sources of the class ActiveMQResourceAdapter, I figured out the following configuration:

deploy --type rar /home/tools/artemis-rar-2.11.0.rar

create-resource-adapter-config  --property connectionParameters='host=localhost;port=61616':JndiParams='java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory;connectionFactory.ConnectionFactory=tcp://localhost:61616;queue.jms/myQueue=Q1':useJndi='true':entries='ConnectionFactory':userName='admin':password='admin' artemis-rar-2.11.0

create-connector-connection-pool --raname artemis-rar-2.11.0 --connectiondefinition javax.jms.ConnectionFactory --ping true --isconnectvalidatereq true jms/ConnectionFactoryPool

create-connector-resource --poolname jms/myConnectionPool jms/myConnectionFactory

create-admin-object --raname artemis-rar-2.11.0 --restype javax.jms.Queue --property PhysicalName=Q1 jms/myQueue

The JNDI-properties are a try to mimic the contents of the jndi.properties from the examples. The good part is, that on startup Payara Micro says:

[2020-03-26T20:51:58.812+0100] [] [INFO] [] [org.apache.activemq.artemis.ra] [tid: _ThreadID=48 _ThreadName=pool-18-thread-1] [timeMillis: 1585252318812] [levelValue: 800] AMQ151007: Resource adaptor started

The bad news is that it then continues with:

[2020-03-26T20:51:58.843+0100] [] [WARNUNG] [] [fish.payara.boot.runtime.BootCommand] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1585252318843] [levelValue: 900] Boot Command create-connector-connection-pool failed PlainTextActionReporterFAILUREInvalid connection definition. Connector Module with connection definition javax.jms.ConnectionFactory not found.

And:

[2020-03-26T20:51:58.850+0100] [] [WARNUNG] [] [fish.payara.boot.runtime.BootCommand] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1585252318850] [levelValue: 900] Boot Command create-connector-resource failed PlainTextActionReporterFAILUREAttribute value (pool-name = jms/myConnectionPool) is not found in list of connector connection pools.

And:

[2020-03-26T20:51:58.856+0100] [] [WARNUNG] [] [fish.payara.boot.runtime.BootCommand] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1585252318856] [levelValue: 900] Boot Command create-admin-object failed PlainTextActionReporterFAILUREResource Adapter artemis-rar-2.11.0 does not contain any resource type for admin-object. Please specify another res-adapter.

So, it fails to register a connection factory and a queue. As a consequence, the application throws exceptions later on when looking up resources.

I have to admit that I am not experienced with JMS and resource adapters / JCAs. It's been frustrating as I have burned days with this already. So, any help with this is welcome.

1

1 Answers

1
votes

Answering my own question now. It feels like it took me ages to figure this out, but I finally got it working. So, the correct configuration with asadmin is as follows:

deploy --type rar /home/tools/artemis-rar-2.11.0.rar

create-resource-adapter-config  --property ConnectorClassName='org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory':ConnectionParameters='host=localhost;port=61616':UserName='admin':Password='admin' artemis-rar-2.11.0

create-connector-connection-pool --raname artemis-rar-2.11.0 --connectiondefinition org.apache.activemq.artemis.ra.ActiveMQRAConnectionFactory --ping true jms/ConnectionFactoryPool

create-connector-resource --poolname jms/ConnectionFactoryPool jms/myConnectionFactory

As you can see, there is no configuration for an admin object. The reason is, that the artemis rar seemingly does not provide any admin object. This ways, you can't lookup your destinations (queues and topics) via jndi, but need to create them with the JMS-session using the destinations physical name. Now, the configuration of the MDB:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "Q1"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "resourceAdapter", propertyValue = "artemis-rar-2.11.0")
})
public class MyMDB implements MessageListener {
    ...
}

There is one problem, though: you can't access the management queue to control the broker. Although you can create the session and the destination, the messages need to be of a certain class. The necessary class, however, is not returned by the configured connection factory leading to exceptions on runtime. So, one needs to search for other approaches to access the management part.

Having said all this, I'd like to share some constructive critics for the case that the devs of Artemis my stumble across this. Although the documentation explains that for Java EE users there is an JCA architecture for artemis, it is nowhere explained how to set it up / configure it. There is not even a link to the rar file on maven (which has a strange goup-id btw). Of course, there is plenty of examples coming with Artemis, but from what I can see there is none showing how to set up the rar. Instead, they are set up using the client-jar, but I doubt this approach would work with MDBs. The point to start with, was the rar-example that showed the configuration properties, but not their values (at least, not for the ConnectorClassName property). One can then only take a look at the sources on github and try to transform the configuration other users used for other application servers. Let me know if I got something wrong with my approach, but things were much simpler to set up with the classic ActiveMQ.