Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jms-dev] JMS 3.0(?) idea: JMS resource declarations without JCA

Greetings.

 

One of the things in JMS 2.0 (or rather Java EE 6) that are incredibly useful in theory, but terrible in practice are resource definitions. @JMSConnectionFactoryDefinition looks a lot like @DataSourceDefinition, but is much more cumbersome to use:

 

- it requires JCA adapters for each message broker, which must be deployed into the application server, are often poorly documented, and even functionally incomplete

- @MessageDriven beans, the place where you would expect to get away with just JNDI names of the factory and the destination plus the destination name, do not work with such JMS resources without vendor-specific ActivationConfigProperties

 

Better @JMSConnectionFactoryDefinition and @JMSDestinationDefinition should possess the following traits:

 

- create JMS resources that are indistinguishable from those created by the application server

- not require any additional wrappers around existing libraries that implement JMS interfaces

- use the same configuration properties as existing JMS libraries

 

This will allow Jakarta EE developers to create applications that work equally well with existing application servers running Java EE 6 or 7 (by not declaring JMS resources in their code) as well as with cloud native lightweight application servers that support the next version of JMS and that can be packaged as uberjars or hollow jars + skinny jars, all this without vendor-specific code.

 

The changes to the annotations, interfaces and the expected behavior that, in my opinion, will achieve that are outlined below the signature.

 

Best regards,

Alexey Marin

 

 

JMSConnectionFactoryDefinition:

 

- when resourceAdapter() is not set, className() is used to select a class from the classpath, not from the default resource adapter; interfaceName() is used to disambiguate in cases when the class implements several JMS connection factory interfaces

- XAConnectionFactory and its subinterfaces are added to the list of allowed connection factory interfaces, the application server must provide their non-XA counterparts as JNDI resources and manage transactions transparently

- it's a runtime error when interfaceName() is XAConnectionFactory or its subinterface and transactional() is false

- user() and password() are used to call ConnectionFactory.createConnection() and ConnectionFactory.createContext()

- when resourceAdapter() is not set, properties() must set the properties of the instantiated connection factory class, which must be a JavaBean

 

 

JMSDestinationDefinition:

 

- when resourceAdapter() is not set, className() is used to select a class from the classpath, not from the default resource adapter; interfaceName() is used to disambiguate in cases when the class implements several JMS connection factory interfaces

- destinationName() must be used to create destinations in a JMS-standard way

- String connectionFactoryLookup() must be added to the interface. It can be used instead of className() or resourceAdapter() to create a destination

 

 

ConnectionFactory:

 

- Queue createQueue(String name) and Topic createTopic(String name) must be added to the interface. Right now the docs say similar methods on Session should not generally be used and JNDI lookup should be preferred, but this simply obscures the facts that application servers and JMS providers still need some API that lets them configure destinations. Putting the methods on the factory provides that common API.

 

 

 

Concerns:

 

- Most Queue and Topic implementations provide a constructor that accepts the destination name as its only String parameter, so changes to ConnectionFactory are theoretically unnecessary, but constructors are not a part of the interface, so I'd prefer two trivial factory methods instead. If some vendors don't provide a compliant implementation, writing a wrapper will still be trivial.

- Low demand for the change. MicroProfile Reactive Messaging is the new hip API, and vendors that provide cloud native Jakarta EE application servers might not be interested in changes that let customers migrate away from their software with ease.

 

 

 

An example of how this might look in practice:

 

@JMSConnectionFactoryDefinition(

  name = "java:app/jms/Artemis",

  className = "org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory"

  //I want XA and I want both queues and topics

  interfaceName = "javax.jms.XAConnectionFactory",

  user = "foo",

  password = "bar",

  properties = {

           "brokerURL=tcp://example.com:61616"

  }

)

@JMSDestinationDefinition(

  name = "java:app/jms/SourceQueue",

  interfaceName = "javax.jms.Queue",

  destinationName = "FOO.BAR.ADAPTER",

  connectionFactoryLookup = "java:app/jms/Artemis"

)

 

These declarations do not require a JCA resource adapter to work, but work with artemis-jms-client directly, which must be packaged with either the application or the application server.

 


Back to the top