Home > Work & Tech > @Resource injection of a Websphere MQ jms topic in Glassfish V3

@Resource injection of a Websphere MQ jms topic in Glassfish V3

June 20th, 2012

So in my day job at ESPN we’ve been using Glassfish & MDBs to do JMS message processing for several years now. But most of our messaging stuff is queue based and we’re only now getting around to upgrading our topic publishers from Glassfish 2.1 to V3.

As per our IBM webshpere MQ support contract, we have to use their wmq.jmsra-7.0.1.4 resource adapter (not the generic JMS adapter that GF comes with).

We ran into an issue when we upgraded from V2 to V3.1 where resource injection of a topic (i.e. @Resource(mappedName="jms/NBATopic") private Topic nbaTopic;) seemed to not work anymore and threw an exception looking something like this:

com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class com.espn.jmstest.SendMsgServletMQ
at
… snip snip …
Caused by: java.lang.IllegalStateException: Exception attempting to inject Unresolved Message-Destination-Ref com.espn.jmstest.SendMsgServletMQ/topic@java.lang.String@null into class com.espn.jmstest.SendMsgServletMQ: Lookup failed for ‘java:comp/env/com.espn.jmstest.SendMsgServletMQ/topic’ in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
… snip snip …
Caused by: javax.naming.NameNotFoundException: NBATopic not found
… snip snip …
… 50 more

Long story short, the problem stemmed from defining the Connector Admin Object Resource via the V3 admin console. This worked fine in V2 but the dialog for it in V3 forces the attribute class-name="com.ibm.mq.connector.outbound.MQTopicProxy" on you (click screenshot).

If you use the admin console you get something like this in your domain.xml – note the class-name attribute which results in the topic resource injection not working (guessing that IBM class not @Resource compliant?).

<admin-object-resource enabled="false" res-adapter="wmq.jmsra-7.0.1.4"
        res-type="javax.jms.Topic" description="" jndi-name="jms/NBATopic"
        class-name="com.ibm.mq.connector.outbound.MQTopicProxy">
    <property name="baseTopicName" value="SA/NBA"></property>
    <property name="baseQueueManagerName" value="QM_ESPN_01_DEV"></property>
</admin-object-resource>

Not sure why V3 added class-name as required but the attribute in the underlying domain.xml is NOT required. So the solution is to simply use asadmin create-admin-object directly so you end up with something like this in your domain.xml (and yes, I know, we should have been real men and used the command line all along!):

<admin-object-resource res-adapter="wmq.jmsra-7.0.1.4"
        res-type="javax.jms.Topic" jndi-name="jms/NBATopic">
    <property name="baseTopicName" value="SA/NBA"></property>
    <property name="baseQueueManagerName" value="QM_ESPN_01_DEV"></property>
</admin-object-resource>

Voila! Same code from V2 works just fine in V3.

Here’s the long back story / full instructions on how to set up Glassfish to talk to Websphere MQ using the IBM RA – hopefully this helps the next poor sucker Googling for it:

  1. Install IBM RA far to GF instance (your MQ distro should come with a file named something like wmq.jmsra-7.0.1.4.rar which can be deployed directly)
  2. Create a connector connection pool specifying wmq.jmsra-7.0.1.4 as the resource adapter and javax.jms.TopicConnectionFactory as the definition (seems it has to be TopicConnectionFactory not generic ConnectionFactory). We set “NoTransaction” and then set the following properties: transportType; channel; hostName; queueManager; port (the value of which obviously depends on your MQ setup). The connection factory should ping successfully in both V2 and V3.
  3. Create a Connector Resource pointing to the pool created in step #2.
  4. Create a Connector Admin Object Resource jms/NBATopic of type javax.jms.Topic specifying the wmq.jmsra adapter and the topic + queue manager properties required by the IBM RA. NOTE*: if you try step 4 using the GF V2 admin console, all is good. If you try it using the V3 admin console, you will run into the class-name attribute problem described above and no workey – so use asadmin create-admin-object in V3 as the GUI has a required dropdown with only the 1 selection !!!

Then the code to get the topic and publish to it is pretty simple and looks something like this:


    @Resource(mappedName = "jms/SPORTSQMTCF")
    private TopicConnectionFactory connectionFactory;

    @Resource(mappedName = "jms/NBATopic")
    private Topic topic;

    ... other stuff ...

    public void send(String msg) throws Exception {
        connection = connectionFactory.createTopicConnection();
        session = connection.createTopicSession(false,
            Session.AUTO_ACKNOWLEDGE);
        messageProducer = session.createProducer(topic);
        textMessage = session.createTextMessage();
        textMessage.setText(request.getParameter(msg));
        messageProducer.send(textMessage);
    }

Categories: Work & Tech Tags:
Comments are closed.