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.
Related
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.
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).
I have recently started using Wildfly 8 and noticed that Wildfly8 has a built-in JMS utility called Hornetq. My question is, how can I configure hornetq to send and receive message on a JMS queue using Wildfly8 server?
There are a number of good tutorials on the net about how to use HornetQ (JMS) from within Widlfly, I like this one for JMS 2.0:
http://www.mastertheboss.com/jboss-server/jboss-jms/jms-20-tutorial-on-wildfly-as
Here is the hello world example from Wildfly themselves, illustrating how to implement an MDB and the respective listeners and topics:
https://github.com/wildfly/quickstart/tree/8.x/helloworld-mdb
That page describes everything in excellent detail and demonstrates the use of JMS 2.0 and EJB 3.2 Message-Driven Bean in WildFly 8. The project is runnable with maven and creates two JMS resources:
A queue named HELLOWORLDMDBQueue bound in JNDI as java:/queue/HELLOWORLDMDBQueue
A topic named HELLOWORLDMDBTopic bound in JNDI as java:/topic/HELLOWORLDMDBTopic
If you are having trouble with configuration of queues etc. in the standalone, the docs here are actually quite helpful as well:
https://docs.jboss.org/author/display/WFLY8/Messaging+configuration
I am a new bie to the world of Spring JMS, I have read the manning Spring in action particular for JMS, I have also gone with through this url and it helped me lot.I have also gone through the official spring reference and discovers the JMS templates also, Now my query is could you please advise me some more urls so that when, I am going to build a small first application which will put data in queue and another app will read data from that queue, so I will be using Active MQ, please share some url and examples to grasp more and that will help me to build the application and explore the world of spring JMS.
Thanks in advance
Follow these links in order:
Using spring to send jms messages
Using spring to receive jms messages
Tuning jms message consumption in spring
Creating robust jms application
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)