users@glassfish.java.net

[gf-users] Re: Glassfish 4.0 b89 Durable Subscriptions

From: STEBBING, MATTHEW L TSgt USAF AFWA AFWA/WDA <matthew.stebbing_at_us.af.mil>
Date: Tue, 6 Jan 2015 19:55:16 +0000

Nigel,

I posted the revised question to the user's group as well but here's the abbreviated version with code:

Have a simple mavenized war project that only contains 2 MDBs, 1 looks like:

        @MessageDriven(name = "testMDB", mappedName = "jms/ExampleTopic",
       activationConfig = {
                       @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "examplesub"),
                       @ActivationConfigProperty(propertyName = "clientID", propertyValue = "exampleID1"),
                   @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
            @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
    })
        public class MDBTest implements MessageListener {
           @Override
           public void onMessage(Message message) {
              System.out.println("RX1: " + message.toString());
           }
        }

the other looks like so:

        @MessageDriven(name = "testMDB2", mappedName = "jms/ExampleTopic",
       activationConfig = {
                       @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "examplesub"),
                       @ActivationConfigProperty(propertyName = "clientID", propertyValue = "exampleID2"),
                   @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
            @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
    })
        public class MDBTest2 implements MessageListener {
           @Override
           public void onMessage(Message message) {
              System.out.println("RX2: " + message.toString());
           }
        }

Have a JMS connection factory setup to point to a local broker - it is called jms/ExampleTopic.

Also have a cluster with 2 nodes setup in Glassfish for which I deploy to and target while deploying my war.

When I attempt to deploy the WAR project with the 2 MDBs outlined above I get the following exception:

Exception while loading the app : EJB Container initialization error java.lang.Exception
 at com.sun.enterprise.connectors.inbound.ConnectorMessageBeanClient.setup(ConnectorMessageBeanClient.java:233)
 at com.sun.ejb.containers.MessageBeanContainer.<init>(MessageBeanContainer.java:205)
 at com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:121)
 at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:230)
 at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:305)
 at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:108)
 at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186)
 at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:264)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:460)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
 at org.glassfish.deployment.admin.InstanceDeployCommand.execute(InstanceDeployCommand.java:187)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:363)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1066)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259)
 at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461)
 at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212)
 at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
 at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
 at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
 at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
 at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
 at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
 at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
 at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
 at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
 at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
 at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
 at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
 at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
 at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
 at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
 at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
 at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
 at java.lang.Thread.run(Thread.java:745)

 Caused by: javax.resource.NotSupportedException: MQRA:EC:Error:createRemoteMessageConsumer failed:aborting due to:[C4052]: Client ID is already in use - exampleID1 user=test_user, broker=BROKER-ADDRESS(44245)
 at com.sun.messaging.jms.ra.EndpointConsumer.createRemoteMessageConsumer(EndpointConsumer.java:478)
 at com.sun.messaging.jms.ra.EndpointConsumer._init(EndpointConsumer.java:308)
 at com.sun.messaging.jms.ra.EndpointConsumer.<init>(EndpointConsumer.java:185)
 at com.sun.messaging.jms.ra.ResourceAdapter.endpointActivation(ResourceAdapter.java:478)
 at com.sun.enterprise.connectors.inbound.ConnectorMessageBeanClient.setup(ConnectorMessageBeanClient.java:225) ... 36 more

 Caused by: com.sun.messaging.jms.InvalidClientIDException: [C4052]: Client ID is already in use - exampleID1 user=test_user, broker=BROKER-ADDRESS(44245)
 at com.sun.messaging.jmq.jmsclient.ProtocolHandler.setClientID(ProtocolHandler.java:2179)
 at com.sun.messaging.jmq.jmsclient.ConnectionImpl.setClientID(ConnectionImpl.java:1932)
 at com.sun.messaging.jms.ra.EndpointConsumer.createRemoteMessageConsumer(EndpointConsumer.java:462) ... 40 more

Please excuse the BROKER-ADDRESS substitution....

NOTES:
> This setup DOES WORK if there is only 1 node in the cluster
> made sure to do (imqcmd) purge dur and destroy dur the broker BEFORE deploying the WAR
> The result is the same if I have just 1 MDB instead of 2
> experiencing this on Glassfish 3.1.2.2, GF 4.0 b89 and GF 4.1 b13

We thought as long as useSharedSubscriptionInClusteredContainer=true (by default) that you should be able to do this. We also attempted to set that property manually on the connection factory itself - also same result.

Appreciate your time in all this.

-----Original Message-----
From: Nigel Deakin [mailto:nigel.deakin_at_oracle.com]
Sent: Tuesday, January 06, 2015 12:56 PM
To: users_at_glassfish.java.net; liang.x.zhao_at_oracle.com
Cc: STEBBING, MATTHEW L TSgt USAF AFWA AFWA/WDA; CORDES, GREGORY M CTR USAF AFWA AFWA/SEMS RM 3250
Subject: Re: [gf-users] Re: Glassfish 4.0 b89 Durable Subscriptions

(For the benefit of readers, we're discussing a long0-established feature of GlassFish called "shared subscriptions", not to be confused with the new JMS 2.0 API feature of the same name).

On 06/01/2015 17:11, MUNDT, CHRISTOPHER J CTR USAF AFWA AFWA/SEMS RM 3250-25 wrote:
>
> A couple months ago you gave us some suggestions to work with GF4.0 and a Durable Topic subscription. At the time
> we had some issues implementing your suggestions because our code was using Spring.
>
> Our developers have since created just a simple MDB app that will
> receive messages from a topic and output contents to the server.log.
>
> After several hours of testing and troubleshooting, we have not been
> able to get this MDB to successfully establish a Durable Shared Subscription to the topic under GF 3.1.2.2, GF 4.0 build 8.9 or GF 4.1 Build 13.

In each of these three cases, were you using a single GF instance or a cluster?

(The only way to tell whether the subscription was shared is to try to deploy it to a cluster and see whether it works).

>
> If we deploy the app to just a single GF instance the app will connect
> successfully, establish a subscription, and receive messages from the topic. However when we try to start up a second instance of GF as part of the cluster, we
> receive errors in both the GF Logs and the OpenMQ logs stating that the ClientID is already in use. At times I have
> also seen messages about a non-shared subscription being made but I don't have that the moment.
>
> Previously our original code worked successfully under GF 2.1.1 but
> have not been able to make it work on anything newer. Our developers
> are out of ideas and we are wondering if anyone has any actually been able to establish and consume messages using a Durable Shared Subscription with multiple Glassfish instances in a cluster??
>
> If so could you point us at an example so we can try to figure what we have misconfigured?

Essentially, if you configure a MDB to use the JMSRA resource adapter to consume messages from a topic, then if you deploy it to a cluster, the subscription should automatically be shared between the MDB instances across the cluster without you needing to do anything.

What activation properties did you use to configure your MDB? Could you paste a fragment from your deployment descriptor or @MessageDriven annotation?

>
> Thanks for your assistance.

There's a little bit of docs here
http://docs.oracle.com/cd/E18930_01/html/821-2438/gjzpg.html

Nigel