users@glassfish.java.net

Re: Trouble connecting MDB to external JMS destination

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Wed, 27 Jun 2012 11:00:48 +0100

Sean,

On 26/06/2012 22:14, Comerford, Sean wrote:
> Hey Nigel,
>
> Yeah, my feeling is you're right – you cannot set the resource adapter name to use anywhere except the ejb-jar.xml

I think you mean glassfish-ejb-jar.xml

>
> I've gotten a bit further at this point but I don't know how to tell the IBM resource adapter what connection factory
> to use.

This is specific to the resource adapter, so it this is possible it will be described in the IBM resource adapter
documentation.

(The EJB 3.1 standard doesn't define a standard way to specify the connection factory used by a MDB. As JMS 2.0 spec
lead I'm trying to fix that)

>
> I have a connection factory resource defined on the instance as jms/UTQueueConnectionFactory but don't see anyway to
> tell the IBM resource adapter to use it.
>
> The generic mms adapter has properties like ConnectionFactoryJndiName and DestinationJndiName but IBM's adapter only
> appears to support an activation JNDI property for the destination and still expects the host, port, etc of the queue
> manager which obviously is not portable between application environments (I.e. dev, QA, prod).

Indeed. If the IBM resource adapter doesn't allow you to specify the JNDI name of a connection factory will may to
hardcode the connection properties (host, port etc) into the MDB's activation config. (Unless IBM allow you to specify
them in the resource adapter config - though I don't think you can)

If you do that, does it work?

>
> I don't suppose anyone out there has successfully pulled this off?

Other experiences welcome.

Nigel

>
> ---
> Sean Comerford
> ESPN.com Architecture & Platforms
>
>
> From: Nigel Deakin <nigel.deakin_at_oracle.com <mailto:nigel.deakin_at_oracle.com>>
> Reply-To: "users_at_glassfish.java.net <mailto:users_at_glassfish.java.net>" <users_at_glassfish.java.net
> <mailto:users_at_glassfish.java.net>>
> Date: Tue, 26 Jun 2012 05:19:10 -0400
> To: "users_at_glassfish.java.net <mailto:users_at_glassfish.java.net>" <users_at_glassfish.java.net
> <mailto:users_at_glassfish.java.net>>
> Subject: Re: Trouble connecting MDB to external JMS destination
>
> Hi Sean,
>
> There's nothing in your MDB configuration to tell GlassFish to use the IBM resource adapter.
>
> The exception you're seeing is from ActiveJmsResourceAdapter - that is because by default it's trying to use the
> built-in JMSRA resource adapter to talk to GlassFish MQ, and you don't want that.
>
> You need to configure the resource adapter in glassfish-ejb-jar.xml (I don't think you can set this anywhere else)
>
> <glassfish-ejb-jar>
> <enterprise-beans>
> <ejb>
> <ejb-name>ejbname</ejb-name>
> <mdb-resource-adapter>
> <resource-adapter-mid>raname</resource-adapter-mid>
> . . .
>
> ...where "raname" is the name of the resource adapter. This is the name you'll have specified previously when you
> created the connection factory and destination objects.
>
> "ejbname" is the fully-qualified class name since you don't set this using @MessageDriven(name="ejbname")
>
> Don't set @MessageDriven(mappedName="...") - that's not used.
>
> Nigel
>
>
> On 25/06/2012 23:23, Comerford, Sean wrote:
>> Using GF 3.1 here.
>>
>> I have a Websphere MQ connection pool and factory defined on my GF instance using IBM's wmq.jmsra RAR.
>>
>> I can publish using this simple servlet code below.
>>
>> / @Resource(mappedName = "jms/UTTopicFactory")/
>> / private TopicConnectionFactory topicConnectionFactory;/
>> /
>> /
>> / @Resource(mappedName = "jms/UTTopic")/
>> / private Topic topic;/
>> /
>> /
>> / protected void processRequest(HttpServletRequest request, HttpServletResponse response)/
>> / throws ServletException, IOException {/
>> ///try { /
>> / String msgText = request.getParameter("msgText");/
>> / sendToTopic(msgText);///
>> / } catch (Exception e) {/
>> / out.print(e.toString());/
>> / }/
>> / }/
>> //
>> / private void sendToTopic(String msgText) throws Exception { /
>> / TopicConnection connection = topicConnectionFactory.createTopicConnection(); /
>> / TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);/
>> / MessageProducer messageProducer = session.createProducer(topic);/
>> //
>> / TextMessage textMessage = session.createTextMessage();/
>> / textMessage.setText(msgText);/
>> //
>> / messageProducer.send(textMessage, DeliveryMode.PERSISTENT, TextMessage.DEFAULT_PRIORITY, 1000);/
>> / messageProducer.send(textMessage);/
>> / messageProducer.close();/
>> / session.close();/
>> / connection.close();/
>> / }/
>>
>> And I read from it using this simple servlet:
>>
>> /_at_Resource(mappedName = "jms/UTTopicFactory")/
>> / private TopicConnectionFactory topicConnectionFactory;/
>> //
>> / @Resource(mappedName = "jms/UTTopic")/
>> / private Topic topic;/
>> /
>> /
>> ///protected void processRequest(HttpServletRequest request, HttpServletResponse response)/
>> / throws ServletException, IOException {/
>> / response.setContentType("text/html;charset=UTF-8");/
>> / PrintWriter out = response.getWriter();/
>> / try {/
>> / out.write("Topic response = " + readTopic());/
>> / } catch (Exception e) {/
>> / out.write("Error: " + e.getMessage());/
>> / e.printStackTrace();/
>> / } finally { /
>> / out.close();/
>> / }/
>> / }/
>> //
>> / private String readTopic() throws Exception {/
>> / String result = null;/
>> //
>> / TopicConnection connection = topicConnectionFactory.createTopicConnection(); /
>> //
>> / TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); /
>> / TopicSubscriber subscriber = session.createDurableSubscriber(topic, "SEAN.TEST");/
>> //
>> / connection.start();/
>> //
>> / TextMessage textMessage = (TextMessage) subscriber.receive(10000);/
>> //
>> / if (textMessage != null) {/
>> / System.out.println("Got " + textMessage.getText());/
>> / result = "Retrieved message from topic: " + textMessage.getText();/
>> / textMessage.acknowledge();/
>> / } else {/
>> / System.out.println("No messages in topic");/
>> / result = "No messages in topic";/
>> / }/
>> //
>> / subscriber.close();/
>> / session.close();/
>> / connection.close();/
>> //
>> / return result;/
>> / }/
>>
>> My (possibly dumb) question is how do I create a MDB that talks to the topic in the same way as the servlet above –
>> by just referencing the JNDI name. Tried this:
>>
>> /_at_MessageDriven(mappedName = "jms/UTTopic", activationConfig = {/
>> / @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),/
>> / @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),/
>> / @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),/
>> / @ActivationConfigProperty(propertyName = "clientId", propertyValue = "MyMDB"),/
>> / @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "SEAN.TEST")/
>> /})/
>> /public class MyMDB implements MessageListener {/
>> //
>> / public MyMDB() {/
>> / }/
>> //
>> / @Override/
>> / public void onMessage(Message message) {/
>> / }/
>> /}/
>>
>>
>> But this won't deploy properly – yields:
>>
>> /SEVERE: Exception while loading the app : EJB Container initialization error/
>> /com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Could not find physical destination : null/
>> /at
>> com.sun.enterprise.connectors.jms.system.ActiveJmsResourceAdapter.getPhysicalDestinationFromConfiguration(ActiveJmsResourceAdapter.java:2068)/
>> /at
>> com.sun.enterprise.connectors.jms.system.ActiveJmsResourceAdapter.updateMDBRuntimeInfo(ActiveJmsResourceAdapter.java:1864)/
>> /at com.sun.enterprise.connectors.inbound.ConnectorMessageBeanClient.setup(ConnectorMessageBeanClient.java:186)/
>> /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:290)/
>> /at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:101)/
>> /at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186)/
>> /at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:257)/
>> /at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)/
>> /at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)/
>> /at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)/
>> /at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)/
>> /at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)/
>> /at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)/
>> /at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)/
>> /at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)/
>> /at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)/
>> /at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)/
>> /at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)/
>> /at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)/
>> /at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)/
>> /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:680)/
>>
>> /
>> /
>> Bear in mind the topic here is an EXTERNAL topic being provided by the web sphere MQ resource adapter.
>>
>> Any help?
>>
>> ---
>> Sean Comerford
>> ESPN.com Architecture & Platforms
>>