configure jndi.xml in serviceMix to work with MQseries - jms

My j2EE app is currently running on ServiceMix. Now i want to add JMS to my app. The application should able to send/receive the JMS message to/from the queue that stays on MQSeries.
mq.hostname=10.3.6.19
mq.channel=CHANNEL
mq.queueManager=QManager
mq.port=1422
What i would like to do is:
1. Create a jndi.xml file and do configuration for jms stuff.
2. my app will initialize the context, look up jndi name, and create a connection, queueManager, queue. .etc
3. Develop send and receive methods.
My question is:
Can you tell me how to do 1st and 2nd steps.
(the script inside ServiceMix's jndi is diffrent with tomcat's
jndi and others.
ServiceMix using Spring based JNDI provider.
http://servicemix.apache.org/jndi-configuration.html)

I just ran into something similar with Weblogic. The following link uses spring-dm to integrate with websphere. It also takes it to the next logical step and adds camel to the mix.
http://lowry-techie.blogspot.com/2010/11/camel-integration-with-websphere-mq.html
Without using Spring-dm, you may run into classloader issues when trying to load the InitialContextFactory from the websphere jar (this is an issue I had with the Weblogic jar)

Related

How to pass Camel VM messages between multiple Spring Boot applications in Tomcat

We have an application stack, deployed in Tomcat, that consists of several Spring Boot applications. As part of our operations, we want to send some messages to a vm endpoint, where a camel route will consume those messages and then publish them to a JMS topic for any of the other Spring Boot applications that are interested in messages on that topic.
When I start the application stack, there are three spring boot apps that utilize camel, and I see camel start properly in the logs. But when one of the apps sends a message to the vm endpoint, the route that consumes from that endpoint and routes the messages to the jms topic does not seem to get that message. I have placed the camel-core jar in my tomcat lib directory. In the spring boot maven plugin configuration, I have specified an exclusion of the camel-core jar. Oddly enough, that jar is in the WEB-INF/lib of the war anyway! So I have stopped Tomcat, removed that jar from the exploded war, and restarted Tomcat, but that does not change the behavior of the messaging.
Here are the versions that we are using:
Spring Boot 2.3.1
Camel 3.4.2
Tomcat 8.5.5
The first spring boot app that links everything together, with the camel route that consumes from the vm endpoint and produces that message on the jms topic is our "routing engine". It uses camel-spring-boot-starter, spring-boot-starter-artemis, camel-vm-starter, artemis-jms-server and camel-jms-starter. Its RouteBuilder's configure method looks like this:
from("vm:task")
.log(LoggingLevel.WARN, "********** Received task message");
.to("jms:topic:local.private.task")
.routeId("taskToJms");
The app that produces messages to the vm endpoint uses camel-spring-boot-starter and camel-vm-starter. In that app, it has a #Service class that receives a ProducerTemplate that is auto-wired in the constructor. When the application invokes this component to send the message, I see a line in the logs that says
o.a.c.impl.engine.DefaultProducerCache (169) - >>>> vm://task Exchange[]
so it appears that the message is being produced and sent properly to the vm endpoint. However, I see no indication that it has been received/consumed in the routing engine's camel route, since the route's log line is not logging anything, and since I see no other indications of receiving the message in the log. The strange thing is that I am not getting the error of not having any consumers on the vm:task endpoint that I was getting before I put the camel-core jar in tomcat's lib directory.
Am I doing anything obviously wrong? How can I get the spring boot maven plugin to really exclude camel-core? And why are the messages (sent to the vm endpoint) not being consumed by the route in the routing engine? Thanks in advance for any help.
Edit: I was able to keep camel-core out of the war files by adding an exclusion to the configuration of the war plugin, but I was still not able to consume the message on the vm endpoint.
I will post the answer, or at least "an" answer, for anyone who might have found themselves in the puzzling situation that I found myself in.
In short, the answer is that it is best to avoid trying to send VM messages across separate contexts within one big JVM like Tomcat. Instead, use something like JMS. I used Artemis, and I stood up an embedded broker in one of the spring boot apps in tomcat. In other apps (that will be clients), I needed to connect to the embedded artemis server, which requires that you add a #Configuration class (in the module that stands up the embedded broker) that implements ArtemisConfigurationCustomizer:
#Configuration
public class ArtemisConfig implements ArtemisConfigurationCustomizer {
#Override
public void customize(final org.apache.activemq.artemis.core.config.Configuration configuration) {
configuration.addConnectorConfiguration("nettyConnector", new TransportConnfiguration(NettyConnectorFactory.class.getName()));
configuration.addAcceptorConfiguration(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
}
}
That lets your other stuff connect to the embedded Artemis broker. Also, you do not have to worry about upgrading camel-core jars in your tomcat shared lib folder when you upgrade camel to a different version. It's good to keep things simple for maintenance purposes!
Anyway, I hope this helps somebody else who might find themselves here someday.

Send a message to wildfly JMS message queue using spring boot

My questions is related to an older post.
I am trying to publish a message to a Wildfly JMS queue. Right now the queues and the app run on the same JBoss container. I am trying to create a new Spring Boot app that can publish messages to the existing queues from another container. Since Wildfly is old I am not finding much help online.
All JMS clients (including Spring JMS) need basic things like JNDI context properties, admin object names, etc. You can refer to the Wildfly Hello World JMS Quickstart for these details and then plug them in to your Spring Boot application. The actual names of the admin objects (i.e. connection factory, queue, etc.) will, of course, vary based on your particular configuration.

In Spring Boot, How do I declare that my JMS server is embedded?

The Spring Boot documentation has this very brief illustration of an embedded JMS server: "Two beans that you don’t see defined are JmsTemplate and ConnectionFactory. These are created automatically by Spring Boot. In this case, the ActiveMQ broker runs embedded." Huh? The Reference Documentation doesn't say a thing about it. I need to create two VMs, each running from its own jar file, and I need one of them to launch an embedded JMS server, but I have no idea how to do this. Can somebody point me in the right direction. (If you provide a link, I would prefer some clear documentation over an example, but I'll be happy with a good example.)
You are looking at the wrong reference documentation. Yours is from Spring Integration.
The one of Spring Boot can be found here:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-activemq
And there you will find the answer:
When ActiveMQ is available on the classpath, Spring Boot can also
configure a ConnectionFactory. If the broker is present, an embedded
broker is automatically started and configured (provided no broker URL
is specified through configuration).

Generic JMS client library for Weblogic, Webshere and JBoss servers

We have a requirement for one standalone Java application that can push JMS message to a JMS queue configured on Weblogic, Websphere and JBoss application server.
Is there any generic JMS client library available, that we can use in our application for pushing the messages to any or all of these servers?
As we understand, there is a specific JMS client for each server (for e.g. wljmsclient.jar required for Weblogic target server, as we would need weblogic.jndi.WLInitialContextFactory to be available as Initial Context factory class, similarly for Websphere and JBoss). And we would like to avoid having 3 different JMS client libraries (1 each for server) in the same application.
However, the catch here is, destination server is not known during compilation time. Only during runtime, it will be known whether the given message is to be pushed to Weblogic, Websphere or JBoss server or all of them. Hence, there is a need for a deployed application to support all 3 servers during runtime.
Is there any alternative generic JMS client library?
You can develop your own client that supports the 3 servers.
Basically you need to have for your standalone application :
The different JMS provider jar on the classpath
For example a jms_config.properties file which stores the configuration for each server (initial context factory, etc.)
Then from a generic code you can build the InitialContext, JMS Queues, etc. depending on the target server.

Deploy MDB on WebLogic 10.3

I am new to MDB, so my questions may sound simple.
I implemented an MDB( serving as a Consumer ) using JDeveloper 11.1.7 and built a JAR file using deployment functionality. Now I need to deploy it to WebLogic 10.3 app server. I have several questions:
1) Should I deploy it as a library or as an application?
2) After I successfully deploy and it's in the "RUNNING" mode I assume it should be listening to the particular Queue I specified as a Resource in my MDB implementation. Is that correct?
3) When implementing an MDB all the examples only specify the "destination" but not the "ConnectionFactory". How does it know where to connect to?
Should I deploy it as a library or as an application?
Deploy as an application since the MDB will likely contain business logic specific to the app.
After I successfully deploy and it's in the "RUNNING" mode I assume it
should be listening to the particular Queue I specified as a Resource
in my MDB implementation. Is that correct?
Yes, if your JMS provider is local, specify the name bound in the local JNDI tree for the destination using destination-jndi-name.
When implementing an MDB all the examples only specify the
"destination" but not the "ConnectionFactory". How does it know where
to connect to?
If the MDB is consuming messages from the local WebLogic JMS provider, the container manages configuration for the connections and sessions automatically, so don't set provider-url, initial-context-factory, or connection-factory-jndi-name, unless you have a custom factory to use.
Refer to WebLogic 10.3 documentation for details:

Resources