Messages appearing again after shutdown / Glassfish + generi

Posted by Admin on 11-Jan-2010 08:55

Hi,

we are connecting Glassfish and Sonic via genericra like this:

https://genericjmsra.dev.java.net/docs/sonic-mq-integration-guide/sonicmq_integration_guide.html

It's working quite well:

Messages are sent to the Sonic - via Sonic Management Console I can see that they appear in the queue.

The MessageDrivenBean receives the messages, too and the Management Console shows that there are zero Messages in the Queue.

But when I shutdown Glassfish or undeploy the application, all sent messages appear in the Queue again!

When I restart/redeploy the application, the MDB receives the messages again. And so on.

I've already asked the genericra mailing list (https://genericjmsra.dev.java.net/servlets/ReadMsg?list=users&msgNo=494). It seems that the configuration is OK.

I double checked with a OpenMQ instance (Glassfish-embedded and remote, too), but that one works as expected: delivered messages don't appear in the Queue again. Same code, just different configuration (connectionfactory and queue).

Does anyone have an idea about this?

Best regards,

Matthias

All Replies

Posted by Admin on 11-Jan-2010 10:12

Here are the exact steps to reproduce this:

First, install Sonic MQ 7.6.

Now follow the steps of chapter "Configuring SonicMQ administered objects" from this guide https://genericjmsra.dev.java.net/docs/sonic-mq-integration-guide/sonicmq_integration_guide.html so that you have:

> list
deadmsgqueue: progress.message.jclient.Queue
inboundXAQCF: progress.message.jclient.xa.XAQueueConnectionFactory
inqueue: progress.message.jclient.Queue
outboundXAQCF: progress.message.jclient.xa.XAQueueConnectionFactory
outqueue: progress.message.jclient.Queue

Then download genericra.rar from
https://genericjmsra.dev.java.net/servlets/ProjectDocumentList?folderID=10248&expandFolder=10248&folderID=7432
and store it in c:\temp\genericra\.

Then start Glassfish (glassfish/bin>asadmin start-domain)  and deploy and configure genericra:

asadmin deploy c:\temp\genericra\genericra.rar
asadmin create-resource-adapter-config --property SupportsXA=true:ProviderIntegrationMode=jndi:UserName=Administrator:Password=Administrator:JndiProperties=java.naming.factory.initial\=com.sonicsw.jndi.mfcontext.MFContextFactory,java.naming.provider.url\=tcp\://localhost\:2506,com.sonicsw.jndi.mfcontext.domain\=Domain1,java.naming.security.principal\=Administrator,java.naming.security.credentials\=Administrator:LogLevel=FINEST genericra

asadmin create-connector-connection-pool --raname genericra --connectiondefinition javax.jms.ConnectionFactory --transactionsupport XATransaction --property ConnectionFactoryJndiName=inboundXAQCF inpool
asadmin create-connector-connection-pool --raname genericra --connectiondefinition javax.jms.ConnectionFactory --transactionsupport XATransaction --property ConnectionFactoryJndiName=outboundXAQCF outpool
asadmin create-connector-resource --poolname inpool jms/inboundXAQCF
asadmin create-connector-resource --poolname outpool jms/outboundXAQCF
asadmin create-admin-object --raname genericra --restype javax.jms.Queue --property DestinationJndiName=inqueue jms/inqueue
asadmin create-admin-object --raname genericra --restype javax.jms.Queue --property DestinationJndiName=outqueue jms/outqueue

Then create a RESTful WS and put it into a web project "webservicejmstest":

@Stateless
@Path("/jms")
public class JMSRestfulWebService {

    @Resource(mappedName = "jms/outboundXAQCF")
    private ConnectionFactory sonicConnectionFactory;

    @Resource(mappedName = "jms/outqueue")
    private Queue sonicQueue;

    @Path("sonic")
    @GET
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String putMessageSonic() throws NamingException, JMSException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
    {
        System.out.println("called putMessageAdapter->Sonic");
        javax.jms.Connection  connection = null;
        javax.jms.Session        session = null;
        MessageProducer messageProducer = null;
   
        try
        {
            connection = sonicConnectionFactory.createConnection();
            session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
            messageProducer = session.createProducer(sonicQueue);
            TextMessage message = session.createTextMessage();
            message.setText("Hello, sonic JMS! #");
            messageProducer.send(message);
           
            return "JMS remotely produced 1 message for sonic #";
        }
        finally
        {
            if (messageProducer != null) try { messageProducer.close(); } catch (Exception ignore) { }
            if (session != null) try { session.close(); } catch (Exception ignore) { }
            if (connection != null) try { connection.close(); } catch (Exception ignore) { }
        }
    }
}

You also need this in web.xml:
   
        Jersey Web Application
        com.sun.jersey.spi.container.servlet.ServletContainer
       
            com.sun.jersey.config.property.resourceConfigClass
            com.sun.jersey.api.core.PackagesResourceConfig
       
       
          com.sun.jersey.config.property.packages
          de.osp.test.webservice
       
        1
   

   
        Jersey Web Application
        /*
   

Call it with a web browser:
http://localhost:8080/webservicejmstest/jms/sonic
and the messages should appear in the "outqueue".

Create a MDB:

package de.osp.test.jms;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "jms/outqueue",
    activationConfig = {
        @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "inboundXAQCF")
        ,@ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue="outqueue")
    }
)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class MySonicRemoteMessageDrivenBean implements MessageListener {

    /**
     * Default constructor.
     */
    public MySonicRemoteMessageDrivenBean() {
        // TODO Auto-generated constructor stub
    }
   
    /**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {
        try {
            System.out.println("### MySonicRemoteMessageDrivenBean got message: " + ((TextMessage)message).getText() + " @" + System.currentTimeMillis());
        } catch (JMSException e) {
            e.printStackTrace();
        }
       
    }

}

And it should receive all messages until the outqueue is empty.
Now shut down Glassfish - the Queue is full again.

This only happens when you have @TransactionAttribute(TransactionAttributeType.REQUIRED).
NOT_SUPPORTED or REQUIRESNEW does work, but doesn't span a XA transaction, though.

Posted by Bill Wood on 13-Jan-2010 12:18

I don't know the specifics of this, but if messages are appearing back on the queue, then it is because you have a Transacted Session and it is not being committed.  When you shutdown the broker, you are rolling back all transactions.

Why this is, I do not know.

(As a side note, I am aware that the SonicMQ JCA adapter is tested against specific RA's, but the genericra is not one of them.  You could be running into an issue here.)

Posted by Admin on 14-Jan-2010 01:50

Thank you for this answer.

This entry says that there is no resource adapter for Glassfish. I'm baffled about this as GF is one of the most popular application servers ATM...

So what chances do I have here?

a) Get genericra to work with Sonic.

I've already tried to provide the genericra developer with debug information but I simply could not enable logging in Sonic so I can see what's happening with the transactions. Is there an easy way to do this?

b) Get a Sonic RA to work with Glassfish.

Where do I find these RAs for Weblogic, jBoss,...?

c) Integrate Sonic as a Foreign JNDI provider into the JNDI tree of Glassifsh.

I will have to ask the GF community about this, as it's not very well documented.

Could someone help with options a and b here?

Cheers,

Matthias

Posted by tsteinbo on 15-Jan-2010 03:24

Matthias,

a) Get genericra to work with Sonic.

I've already tried to provide the genericra developer with debug information but I simply could not enable logging in Sonic so I can see what's happening with the transactions. Is there an easy way to do this?

b) Get a Sonic RA to work with Glassfish.

Where do I find these RAs for Weblogic, jBoss,...?

re a) the broker does not log jms transactions. XA transactions can be monitored in the brokers's manage tab (SMC).

re b) You can download the from the Progress ESD at www.progress.com/esd. Locate the Progress® SonicMQ® Resource Adapters for JCA package.

Posted by Admin on 18-Jan-2010 11:49

Hi,

for now I was successfull connecting Glassfish and SonicMQ via JMSJCA.

See my little tutorial about this:

http://www.tricoder.net/blog/?p=144

I will try to find time and check the synchronuous mode of genericra, though.

Best regards,

Matthias

This thread is closed