0
votes

I am trying to configure a MDB in Glassfish 3.1.2 to listen on a remote JMS Queue (MQ 7 via GenericJMSRA 2.0.1).

When I try to use the JNDI names to define my MDB like this

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "jms/MyQueue"),
    @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "jms/MyFactory") })
@TransactionManagement(TransactionManagementType.BEAN)
public class SimpleMdb implements MessageListener { ... }

I get this error (minimal extract from the stacktrace):

java.lang.RuntimeException: EJB Container initialization error
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:242)
Caused by: java.lang.Exception
    at com.sun.enterprise.connectors.inbound.ConnectorMessageBeanClient.setup(ConnectorMessageBeanClient.java:233)
Caused by: javax.resource.spi.InvalidPropertyException: MyFactory
    at com.sun.genericra.util.ExceptionUtils.newInvalidPropertyException(ExceptionUtils.java:42)
Caused by: javax.naming.NameNotFoundException: MyFactory
    at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(RefFSContext.java:400)

If I use the names of the Factory and Queue as defined in the .bindings file and in the resource-adapter definition like shown below, it works fine.

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "SOME.REALLY.UGLY.LONG.NAME"),
    @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "THE_NAME_OF_THE_FACTORY") })
@TransactionManagement(TransactionManagementType.BEAN)
public class SimpleMdb implements MessageListener { ... }

When I only replace the factory's JNDI name with the "ugly" one, I get the same stacktrace as above but referring to the "MyQueue".

At the same time my setup of .bindings file, resource-adapter definition in the domain.xml (inserted via a tool) and queue usage in EJBs/Servlets seems to be fine. I can use the queue and its connection factory in the usual an desired way - this works fine:

QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/MyFactory");
Queue asyncQueue = (Queue) ctx.lookup("jms/MyQueue");

Can someone provide insight on why this is happening? I would like to use the JNDI names like "jms/MyQueue" everywhere in the code - including the MDB definition.

Here is the relevant section of my domain.xml:

<resource-adapter-config thread-pool-ids="genericra-thread-pool" resource-adapter-name="genericra">
  <property name="SupportsXA" value="false"></property>
  <property name="ProviderIntegrationMode" value="jndi"></property>
  <property name="RMPolicy" value="OnePerPhysicalConnection"></property>
  <property name="LogLevel" value="FINEST"></property>
  <property name="JndiProperties" value="..."></property>
</resource-adapter-config>
<connector-connection-pool name="genericra-pool-1" resource-adapter-name="genericra" is-connection-validation-required="true" connection-definition-name="javax.jms.QueueConnectionFactory" fail-all-connections="true" transaction-support="NoTransaction">
  <property name="ConnectionFactoryJndiName" value="THE_NAME_OF_THE_FACTORY"></property>
</connector-connection-pool>
<connector-resource pool-name="genericra-pool-1" jndi-name="jms/MyFactory"></connector-resource>
<admin-object-resource res-adapter="genericra" res-type="javax.jms.Queue" jndi-name="jms/MyQueue">
  <property name="DestinationJndiName" value="SOME.REALLY.UGLY.LONG.NAME"></property>
  <property name="Name" value="jms/MyQueue"></property>
</admin-object-resource>
  • GlassFish 3.1.2.9
  • WebSphere MQ 7
  • genericra 2.0.1
  • Java 1.7/JEE 6/EJB 3.1
2

2 Answers

1
votes

The general assumption is that there is something missing in the JNDI - how is the JNDI being populated? It looks like this is the File system context based on the stack trace and the .bindings file you mention.

It's worth noting as well that WMQ has it's own Resource Adapter - there's no need to use the generic one here. Might be an avenue to explore?

0
votes

By now we managed to find a solution. With genericra it is not possible to redirect MDBs to a JNDI name that is given by genericra to the resource. Instead the MDB has to reference the name of the Queue as defined by the .bindings file (on the left side, not the remote name on the right side). Luckily we were able to adapt the .bindings files to our needs.

Now we may use the JNDI name given to the resource in the genericra configuration for "normal" use in the code like this:

QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/MyFactory");
Queue asyncQueue = (Queue) ctx.lookup("jms/MyQueue");

But MDBs have to use the name as given in the .bindings:

@ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "QUEUE_NAME_IN_BINDINGS")