users@glassfish.java.net

[gf-users] Re: GF3+ Issue with Shared Durable Subscriptions

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Wed, 07 Jan 2015 10:54:29 +0000

Matthew,

This all looks fine, so it's not immediately obvious what the issue is. And I see my colleague David Z reports that he
was able to deploy this into a GlassFish 4.1 cluster and sent you something to try.

> I thought as long as useSharedSubscriptionInClusteredContainer=true (by default) that you should be able to do this.

That is correct. And since the default is true you can simply omit this property.

> I also attempted to set that property manually on the connection factory itself - also same result.

Which connection factory? Your MDB doesn't specify a connection factory - which is fine and normal.

> As you can see, the publisher does not specify a client ID either -

The clientID of the publisher is irrelevant and has no effect on what happens when messages are sent. If you do set it
for some reason then it *must *be different from the one used by the MDB.

> so I'm guessing the broker is having issues with the fact that there are mutliple copies of the MDB - being clustered.

Essentially, when the MDB is running in a clustered GlassFish container it sends a flag to the broker to tell the broker
that it needs to allow the two sets of MDBs to supply the same clientID and to share the subscription between them. This
should all happen automatically, but obviously something is going wrong in your case.

I know that configuring a Glassfish cluster is very easy and it's unlikely you've done it wrong, but is there any
possibility that you don't actually have a cluster?

Nigel


On 06/01/2015 19:02, Matthew S wrote:
> Hello GF users,
>
> running into an issue with shared durable subscriptions
>
> have the following fairly simple situation:
>
> 2 projects:
> I 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());
> }
> }
>
> I have a JMS connection factory setup to point to a local broker - it is called jms/ExampleTopic.
>
> I also have a cluster with 2 nodes setup in Glassfish for which I deploy to and target while deploying my war.
>
> The other project is a simple command line jar that acts as a test publisher, here's a snippet of the code block (note
> that now I have contants for many of the properties):
>
> TopicConnection topicConnection = null;
> TopicPublisher topicPublisher = null;
> Topic topic = null;
> TopicSession topicSession = null;
> com.sun.messaging.TopicConnectionFactory topicConnectionFactory = null;
>
> topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory();
> topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, ADDR);
> topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqReconnectEnabled, "true");
> topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressListBehavior, "RANDOM");
> topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqDefaultUsername, "test_user");
> topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqDefaultPassword, "test_user");
>
> try {
> // create topic connection and pass over the client id
> topicConnection = topicConnectionFactory.createTopicConnection();
>
> // not transacted, do auto acknowledge
> topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
> topic = new com.sun.messaging.Topic(TOPIC);
> topicPublisher = topicSession.createPublisher(topic);
>
> topicConnection.start();
>
> TextMessage msg = topicSession.createTextMessage();
> msg.setText(TX);
>
> topicPublisher.send(msg);
>
> } finally {
> if (topicConnection != null) {
> topicConnection.stop();
> topicConnection.close();
> }
> }
> }
>
> Fairly straight-forward - just posting a text message to the jms/ExampleTopic topic.
>
> 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 cluser
> > I made sure to 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
> > I'm experiencing this on Glassfish 3.1.2.2, GF 4.0 b89 and GF 4.1 b13:
>
> I thought as long as useSharedSubscriptionInClusteredContainer=true (by default) that you should be able to do this. I
> also attempted to set that property manually on the connection factory itself - also same result.
>
> As you can see, the publisher does not specify a client ID either - so I'm guessing the broker is having issues with
> the fact that there are mutliple copies of the MDB - being clustered.
>
> Any advice on this?
>