JNDI name format of JMS queue in wildfly10 - jms

Hi I am migrating to wildfly 10 from JBoss_6.1.0_final.
In JBoss for Queue name the format is like
<queue name="TEST_QUEUE">
<entry name="/queue/TEST_QUEUE"/>
</queue>
and in MDB annotation is
#ActivationConfigProperty(propertyName = "destination",
propertyValue = "queue/TEST_QUEUE")
Now in wildfly its like below. reference link
<jms-queue name="TEST_QUEUE" entries="jms/queue/TEST_QUEUE java:jboss/exported/jms/queue/TEST_QUEUE"/>
with activationproperty
#ActivationConfigProperty(propertyName = "destination",
propertyValue = "jms/queue/TEST_QUEUE")
In wildfly I have tried by removing the jms/ from queue name and from annotation, its working fine in wildfly with same queue name ,
like
<jms-queue name="TEST_QUEUE" entries="queue/TEST_QUEUE java:jboss/exported/queue/TEST_QUEUE"/>
Now my question is, Is JMS/ in queue name added purposefully.
it is good practice to write queue name without prefix jms/

From the JEE JSR part EE.5.7.1.2 Programming Interfaces for Resource Manager Connection Factory References
This specification recommends, but does not require, that all resource manager connection factory references be organized in the subcontexts of the application component’s environment, using a different subcontext for each resource manager type. For example, all JDBC™ DataSource references should be declared in the java:comp/env/jdbc subcontext, all JMS connection factories in the java:comp/env/jms subcontext, all JavaMail connection factories in the java:comp/env/mail subcontext, and all URL connection factories in the java:comp/env/url subcontext. Note that resource manager connection factory references declared via annotations will not, by default, appear in any subcontext
the jms subcontext is not mandatory. It is just a best practice.
Servers can or not follow this pattern. JBoss was not following this, wildfly is, but ultimately, it is YOUR decision to do what you want. But this is a really good practice to follow as it is cleaner for everybody.

Related

Adding ActiveMQ as a JMS Provider, Topic Connection Factory and Topic definitions

I am trying to add ActiveMQ as a JMS Provider in Websphere Application Server.
I have followed the instructions described here ActiveMQ 5.11 with WebSphere Application Server 8.5 and adapted to the topic.
Unfortunately I am not sure what I need to add in External JNDI name for both Topic Connection Factory and Topic definitions.
As per IBM documentation:
"External JNDI Name The JNDI name that is used to bind the queue into
the application server name space.
As a convention, use the fully qualified JNDI name; for example, in
the form jms/Name, where Name is the logical name of the resource.
This name is used to link the platform binding information. The
binding associates the resources defined by the deployment descriptor
of the module to the actual (physical) resources bound into JNDI by
the platform."
From my understanding this should be the name that I am using in my app to access the resource defined in WAS.
I also have added the resources in my deployment descriptor as resources.
Any help would be highly appreciated.
Regards
Given that you are accessing the resources via resource references (defined in your deployment descriptor), the configured JNDI name should match the lookup name that is defined in your resource reference.
For example, if your resource reference looks like this,
<resource-ref>
<res-ref-name>java:comp/env/jms/topicConnectionFactoryRef</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
<lookup-name>jms/myTopicConnectionFactory</lookup-name>
</resource-ref>
or if your resource-ref lacks lookup-name and you instead have a ibm-web-bnd.xml file with a binding-name,
<resource-ref name="java:comp/env/jms/topicConnectionFactoryRef"
binding-name="jms/myTopicConnectionFactory">
</resource-ref>
then specify jms/myTopicConnectionFactory as the JNDI name.
Application code will then be able to do:
TopicConnectionFactory tcf = InitialContext.doLookup("java:comp/env/jms/topicConnectionFactoryRef");
Application code could also perform a direct lookup of the JNDI name as follows (although using the resource reference is preferred because it is more spec compliant and standard across app servers),
TopicConnectionFactory tcf = InitialContext.doLookup("jms/myTopicConnectionFactory");
The same applies to javax.jms.Topic.
If your resource environment reference in your deployment descriptor looks like this,
<resource-env-ref>
<resource-env-ref-name>java:comp/env/jms/topicRef</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
<lookup-name>jms/myTopic</lookup-name>
</resource-env-ref>
or if your resource-ref lacks lookup-name and you instead have a ibm-web-bnd.xml file with a binding-name,
<resource-ref name="java:comp/env/jms/topicRef" binding-name="jms/myTopic">
</resource-ref>
then specify jms/myTopic as the JNDI name of the Topic.
Application code will then be able to do:
Topic topic = InitialContext.doLookup("java:comp/env/jms/topicRef");
Some optimizations/special cases:
If you have neither lookup-name nor binding-name, then WebSphere Application Server computes a default binding via the resource reference name. If this is the case for your resource reference, then you will have a deployment descriptor such as the following without any bindings file,
<resource-ref>
<res-ref-name>jms/myTopicConnectionFactory</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
</resource-ref>
In the above case, specify jms/myTopicConnectionFactory as the JNDI name.
The application will be able to look it up as,
TopicConnectionFactory tcf = InitialContext.doLookup("java:comp/env/jms/myTopicConnectionFactory");

Connecting ActiveMQ Web-Console to an existing broker (instead of starting a new one)

Having deployed the activemq-web-console war into a Tomcat embedded application how can one make it connect to an existing broker rather than create a new one?
The war comes with a set of predefined configurations, in particular, the WEB-INF/activemq.xml contains a configuration for the BrokerService
<broker brokerName="web-console" useJmx="true" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter><kahaDB directory="target/kahadb"/></persistenceAdapter>
<transportConnectors>
<transportConnector uri="tcp://localhost:12345"/>
</transportConnectors>
</broker>
used from webconsole-embedded.xml in the following manner:
<bean id="brokerService" class="org.apache.activemq.xbean.BrokerFactoryBean">
<property name="config" value="/WEB-INF/activemq.xml"/>
</bean>
This configuration creates a new instance of BrokerService and tries to start the broker.
It is reported that the web console can be used to monitor an existing broker service rather than creating a new one. For this one should set the following properties somewhere:
webconsole.type=properties
webconsole.jms.url=tcp://localhost:61616
webconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-trun
The questions is, where does one have to set these properties within the Tomcat embedded app and which XML changes in the above have to be performed for them to be used. I cannot find any sensible explanation how to configure it, and a BrokerService instance seems to be required by the remaining spring config.
Any ideas?
Please do not suggest to use hawtio instead!
I had the same problem today. You can start the webconsole in "properties" mode which gives you the oppertunity to connect over jmx.
I added following java arguments to our Jboss 6.1 and it worked immediatley. I didn't change any of the xmls (works out of the box)...
Example:
-Dwebconsole.type=properties -Dwebconsole.jms.url=tcp://<hostname>:61616 -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://<hostname>:1090/jmxrmi -Dwebconsole.jmx.user=admin -Dwebconsole.jmx.password=123456
Also discussed here: https://svn.apache.org/repos/infra/websites/production/activemq/content/5.7.0/web-console.html

Difference between DefaultJMSConnectionFactory and JmsXA

Out-of-the-box, Wildfly 10 configures a pooled connection factory as part of the JMS subsystem with two entries.
<pooled-connection-factory name="activemq-ra"
transaction="xa"
connectors="in-vm"
entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"/>
One might inject a connection factory like so:
#Resource(mappedName = "java:jboss/DefaultJMSConnectionFactory")
private ConnectionFactory connectionFactory;
What is the difference between this and choosing the other entry; java:/JmsXA?
There is no difference it's an additionnal JNDI entry to suit JMS 2 spec default ConnectionFactory name : java:comp/DefaultJMSConnectionFactory
You should resolve it using this name.
Since JMS 2.0, a default JMS connection factory is accessible to EE
application under the JNDI name java:comp/DefaultJMSConnectionFactory.
WildFly messaging subsystem defines a pooled-connection-factory that
is used to provide this default connection factory. Any parameter
change on this pooled-connection-factory will be take into account by
any EE application looking the default JMS provider under the JNDI
name java:comp/DefaultJMSConnectionFactory.
See https://docs.jboss.org/author/display/WFLY9/Messaging+configuration
The other one is just a legacy identifier :
The JCA layer intercepts the calls to createConnection() and createSession() and provides a caching layer (amongst other things). So when you call createConnection() or createSession(), then, in most cases it's not really calling the actual JMS implementation to actually create a new JMS connection or JMS session, it's just returning one from it's own internal cache - in other words the JCA layer pools JMS connections and JMS sessions.
In JBoss application server, the "special" JMS connection factory which provides the JCA caching is usually available at java:/JmsXA in jndi.
See https://developer.jboss.org/wiki/ShouldICacheJMSConnectionsAndJMSSessions

How to configure Wildfly JMS connection factory and destination

I have migrated recently from Glassfish 4 to Wildfly 8.1
I have configured JMS Connection Factory and Destination in Glassfish as:
connection factory------------------------------
jndi name: emailConnectionFactory
resource type: javax.jms.QueueConnectionFactory
destination ------------------------------------
jndi name: emailQueue
resource type: javax.jms.Queue
In Wildfly I go to Configuration->Messaging->Destinations->Connection Factories and enter values name and jndi name as above. but it tells me that jndi name must start from 'java:/' or 'java:jboss/'.
I tried to use jndi name as 'java:/ConnectionFactory' and destination and in Configuration->Messaging->Destinations->queue/topics jndi name as 'java:/jms/queue/emailQueue'
but it didnt gave me and exception and didnt send email with previous email setting
Do the same configuration in standalone-full.xml file .
link1
link2
cool. our team is also doing the same thing - migrating a huge glassfish4 app to wildfly.
Keep this in mind,
For connection factory must be prefixed with java:/ or
java:jboss/exported/ (for remote access).
For queues and topics, use the same rule. Any jms-queue or jms-topic which needs to be
accessed by a remote client needs to have an entry in the
"java:jboss/exported" namespace.

how to read a jms queue from a non hosted java application?

I'm trying to read messages from a jms queue created in "Sun App Server" from a non-hosted application (console app) but I get the following error:
NoInitialContextException
Cannot instantiate class: javax.jms.TopicConnectionFactory
with this code:
Properties env = new Properties( );
env.put(Context.INITIAL_CONTEXT_FACTORY, "javax.jms.TopicConnectionFactory");
InitialContext jndi = new InitialContext(env);
and I have referenced the j2ee.jar library that contains the class but certainly, the class is an interface.
Can I access the queue from a non-hosted application??
Aitor;
When you say "Sun App Server", I'm not sure what that means, but I will assume it is Glassfish.
There are 2 separate steps to acquiring remote JMS resources.
You need to create a remote JNDI connection which requires a valid InitialContextFactory class name.
Once you have a the connection, you can look up the TopicConnectionFactory.
For item #1, this link demonstrates how to make a remote JNDI connection.
For item #2, once you have a JNDI context, you will also need to know the JNDI name of the TopicConnectionFactory which will look something like:
TopicConnectionFactory tcf = (TopicConnectionFactory) jndi.lookup("jms/TopicConnectionFactory");
One aspect you need to keep in mind is that the j2ee.jar library contains the generic Java EE interfaces for the JMS classes, but you will also need a library in your classpath that contain the JMS implementation concrete classes. This also goes for the JNDI connection. This tutorial provides a concise list as:
Applicationserver JNDI Lookup
/lib/appserv-rt.jar
/lib/appserv-admin.jar
/lib/javaee.jar /lib/j2ee.jar
Client Lib
/imq/lib/jms.jar
/imq/lib/imq.jar
/imq/lib/imqutil.jar
/lib/install/applications/jmsra/jmsra.jar

Resources