The simplest JMS request/reply I could come up with for ActiveMQ and JBoss A-MQ

In case you find yourself needing to set up some JMS request/reply code, I hope this helps (the whole example, including writing this post took less than one hour for me). It’s the simplest example I could come up with for ActiveMQ (and JBoss A-MQ, of course). By simple  I mean it focuses as much on the simple task as possible without adding any other frameworks, magic tricks, or whatever — just pure JMS API.

First, create the request message

Here’s the code:

You’ll notice that, compared to a simple send method, the request/reply is a little more complicated in the following ways: you need to create a temporary reply queue (goes in the JMSReplyTo header), a correlation ID (JMSCorrelationID), and then start listening for a reply message.

When you run this, you should see the following if you log into JBoss A-MQ and browse the messages (ActiveMQ lets you do something similar through its web interface too):


Notice the JMSCorrelationID and the JMSReplyTo headers are set.

Next, subscribe and reply

The code to respond to the message mirrors the sender’s code:

Assuming that the sender code is running, if you run the code above, you should then see this in your IDE or console:


The full code is available on Github. Good luck out there, and let me know how this demo goes for you.

The simplest OSGi / Karaf hello, world demo I could come up with

I don’t know about you, but I almost gave up looking for quick and lightweight examples on how to get started creating and deploying an OSGi bundle. Everything I found used out of date or opaque Maven plugins, proprietary techniques specific to a platform, magic tooling called “bnd,” and all kinds of other chaos. I repeatedly hear that precisely this chaos slows down OSGi adoption and related technologies like Camel. I hope this post speeds you up a little.

First, let’s write some Hello, World code

This is the easiest part. I just wanted a simple example that prints hello, world to the console when the bundle starts. Here’s the code I came up with:

You probably noticed you’re going to need the OSGi framework on your classpath. Here are the dependencies I used (but I haven’t researched whether both are strictly necessary or not):

UPDATE (August 2019): Please see Paul’s comment below noting that the the artifacts I listed below are pretty old. He reported that he fixed the issue by adding a line to the manifest file: “fix[ed] this by adding ‘Bundle-ManifestVersion: 2’ to the MANIFEST.MF file.”

Hand craft a file – You. Can. Do. It.

This was the big hurdle for me. It seems that most of the authors of the examples I found had some kind of allergy to hand writing the file, so they rely on various tooling to write it and bundle it. I suppose in real life I might get used to the tooling, but it just gets in the way of me learning. So here’s my hand crafted file:

Bundle-SymbolicName and Bundle-Version lets you describe what the bundle will look like to a user in Karaf (or whatever OSGi container, I suppose). For example:


Import-Package is critical. In fact, it’s a core part of the OSGi concept that you must explicitly declare the services you’re depending on. Remember how we imported the OSGi dependencies in the hello, world Java code? You might have thought that installing a bundle would implicitly include the framework, but you’d be wrong. You have to explicitly declare it.

Export-Package is a similar concept. You need to expose your services to other bundles. Finally, Bundle-Activator is the class you want to fire up on start (the hello, world code above).

Also (Aug 2019 update): see note from above that now that those artifacts are getting a little old you may need to add a Bundle-ManifestVersion: 2 line as well, but I haven’t tried this for myself.

Structuring your project

I put my manifest file under src/main/resources/META-INF:


The wrinkle here is that Maven will overwrite your META-INF file unless you override the default behavior with this:

Finally. Now let’s install and start the bundle

I ran this in Karaf, so here’s what I did. First, run mvn install to get the artifact into your local repository. Next, start up Karaf and run this command:


Take note of the bundle ID. Mine was 95 in this example, but it varies each time. Now let’s start it with this command:

And you should see something like this:


The full example is here: Good luck out there.

How to get the Apache Camel tooling features into your JBoss Developer Studio

This feature — as of this writing — isn’t immediately obvious, so in case you’re trying to figure out how to visually design, test, and run Apache Camel routes in your JBoss Developer Suite, here’s what I’ve got:

When JBDS starts, you get the JBoss Central welcome screen by default, right? There’s a tab at the bottom called “Software/Update.” Click it. Near the bottom right, you’ll see an option to “Enable Early Access.” Click that too.

I’m don’t know when it will get out of early access. If you’re from the future and you’re reading this, things may be different. For now, you should see this:


Select the JBoss Fuse Development, like I did in the example above. Click that too. Now you’ll see this:


The most important to you is probably the Apache Camel Editor, so check it, click Next, and you should be on your way.

Did I join the ActiveMQ Developers list at a great time, or what

I joined the ActiveMQ Developers list to watch the sausage getting made. Maybe I just joined at a good time, or maybe it’s just always this entertaining…?

The background and the vote: Red Hat is donating HornetQ to the Apache Foundation. The ActiveMQ project management committee (“PMC”) needs to report to the board what they should name it and where they should house it. The community narrowly voted to rename it ActiveMQ Artemis instead of ActiveMQ Reactive (I thought reactive was a little confusing too).

The fight: a few of the developers suggested that HornetQ — I mean Artemis — should go to an incubation process first, but that turned out to not be the real issue. No, the real issue appears to be fears or paranoia concerns that the Fuse and Red Hat committers are controlling the code, the process, and effectively masterminding the ASF.

The way it looks is that Fuse/RH/(the Damarillo group), anyway you want to describe that faction is dead set on replacing the existing ActiveMQ with HornetQ (or whatever code name) in version 6 or 10. By keeping HornetQ under the ActiveMQ PMC influence its future will be heavily influenced by the already biased PMC and at the same time hide the lack of diversity in HornetQ. In the incubator, HornetQ will have the opportunity and freedom to grow in any direction and build a diverse community.

Then a response:

We’ve had lots folks from different companies agree with the direction that code contribution is going in. The fact that pin it on ‘Fuse/RH/(the Damarillo group)’ is very disingenuous and I think a poisonous position to take.

Then someone dropped words like evil, conspiracy, and even junta:

Which committer, specifically, could be brought into the PMC to try to counterbalance the alleged RH junta? I’m really discouraged by the insistence from a couple people that the only possible explanation of where we are now is an evil Winston/Fuse/RedHat conspiracy. I think it’s also just barely possible that after working all day people get tired. After providing unpaid all-waking-hours support for first jboss and then geronimo for many many years I sure did. This is not to say that there isn’t a strong need for more community involvement, but expecting the same people to do everything all the time is getting implausible.

Then getting HornetQ into the incubater became a matter of sacrificing oneself to protect Apache values:

Why not be open about it, advocate for it, work for it and build consensus and acceptance instead of putting everybody in front of a ‘take it or leave it’ choice. That’s what rubbed me the wrong way. That’s really not like the ASF I know. That’s why I made a conscious decision to be vocal about it and, in my mind, do my best to protect this community. This may cost me some personal relations, with people like you who are really extremely intelligent and
still do respect

Remember the Junta / Fuse / conspiracy stuff? Here’s one response from one of the alleged but as yet unindicted co-conspirators:

You are the second person to allege that I am acting with secret instructions and communications on this. I demand a pubic apology, immediately. I have done no such thing, all my communications with anyone about this issue have been on this list, and in reply to others raising similar issue on the pmc list. This is disgusting.

Who knew enterprise software could be so… dramatic.

UPDATE: the next morning, my IRC lit up with more conversation from some of the core ActiveMQ folks about yesterday’s discussions. Generally, they seem to think they discussions are good because they indicate people care passionately about ActiveMQ. And then this article appeared:

Ultimately, open source isn’t about code. It’s about community, and as Bert Hubert suggests, “community is the best predictor of the future of a project.” That community isn’t fostered by jerk project leads or corporate overlords pretending to be friendly foundations. It’s the heart of today’s biggest challenges in open source — as it was in the last decade.

Demo: JBoss A-MQ, Websockets/HTML5, and Gordon Gecko

Back in early 2013, Eric Schabell, a Red Hat JBoss evangelist, created a cool JBoss A-MQ demo based on HTML5 websockets. You can see the YouTube demo here and access the JBoss Github repo for the demo here.

I wanted to work through it myself; only, it didn’t work for me out of the box. I fixed it and submitted a pull request, but while we’re waiting for the JBoss folks to accept the PR (’cause you know they should!), you can use the changes on my fork. Plus, I’ll help you out if you hit issues (I’m a consultant, you know…). But let’s walk through the demo for fun and clarification.

Running the demo

The README in the demo repo has all the nitty gritty details you need, but you might want an overview first since it’s a little more involved than just firing up a web application.

  1. Download a recent copy of JBoss A-MQ 6.1 from the JBoss Developer site and copy it to the “installs” directory — even if you already have A-MQ installed.
  2. Run the script to build all the artifacts you need and to provision the A-MQ installation correctly.
  3. Start the “feeder” standalone client, which will start putting stock price (and news) messages on JMS topics.
  4. Install the Websocket OSGI features as well as the demonstration web app.

What it looks like when you stay on the demonstration’s happy path

You’ll start the Karaf command-line client (from target/{amq_version}/bin).


After installing the websocket application, you’ll see installed near the end of the osgi:list:


Next, you’ll start your feeder application from the support directory (support/ You should start seeing messages flowing into the A-MQ topic such as the following:


Finally, you’ll load up a web browser and start seeing messages flowing through websockets to update web stock prices dynamically:


What the demonstration does under the hood

The demonstration shows really well, but you’re probably interested in what’s happening under the hood and how it may (or may not) apply to the work you actually do.

How the demonstration initialization script provisions the A-MQ server

First of all, you might bristle a little at the init script. Let’s talk about what it does because it’s not as black box or magical as it might appear.

  1. It unpacks the JBoss A-MQ installation you downloaded and puts it in the target directory.
  2. It copies over some configuration files. These files mostly just add security accounts so the feeder and client UI can interact.
  3. It runs Maven builds on the feeder and web UI clients so you can (a) run the feeder script and (b) install the web application and websocket features.

The Java code for the message producer and consumers

There are two Java applications that ship with the demo. The “feeder” application puts fake stock and news updates on two JMS topics: stockQueueTopic and newsTopic. The following is just a snippet from FeedThread on how the feeder applcation accesses A-MQ and the topics I just mentioned:

The Websocket-based client code uses the STOMP protocol through Jeff Mesnil’s stomp.js client code. One you login, it starts sending websocket frames to populate the screen I showed you above.


Cool, huh? You might bump into issues out there, so let me know what we can do to improve it.

How to configure a Jenkins job to deploy to JBoss AS/EAP from Artifactory or Nexus using the JBoss CLI

PROBLEM: you’ve got your Jenkins continuous integration jobs running just fine. You’ve got your Jenkins-driven snapshot and release jobs doing what you need them to do, including uploading the artifacts to Artifactory or Nexus. But now you want to actually deploy those artifacts from the Artifactory or Nexus repository to a running JBoss AS7/EAP6 server instance without rebuilding the project. In other words, you don’t want to rely just on JBoss deployment plugin, slick as it is.

SOLUTION: create a new Jenkins freestyle job that (1) uses Maven to download the artifact and then (2) uses the JBoss CLI to run the “deploy” command. In my instance, my servers were running in domain mode.


Configure a new Jenkins job

Creating the job is straightforward and probably familiar to you. Set it up as a “Freestyle project.”


To make the job really flexible, I use a free form list of parameters. (It might be too much flexibility, so see my notes below.)


Here’s the full list of build parameters I configured:

  • groupId – corresponds to the first of the four parts of Maven coordinates, as in groupId:artifact:version:packaging
  • artifact
  • version
  • packaging, which I set up as a “choice” option so it was prepoluated with war, jar, and ear
  • controller – this refers to the domain controller, but could be your standalone server instance
  • as_user – the JBoss AS administrative user account
  • as_password – password for the administrative user
  • server_group – the server group to be used in the domain-based deployment (if you’re running in standalone, you won’t need this)

Run this script as the Jenkins build

In a Linux environment, you pick up the parameters you configured above using the dollar sign and curly braces. In Windows, you’re going to wrap the variable name with percentage symbols. For example, ${groupId} would be %groupId%.

The first step in the script is to download the artifact — wherever it may live by using Maven’s built in artifact resolution technology. Some solutions I saw proposed hacking your want through the HTTP server URLs that power Maven, but I think this would be too difficult to maintain. Besides, the mvn dependency:get plugin does this for us — it resolves and installs the dependency, whatever it may be, for us.

The dependency:get plugin is useful, but it simply puts the artifact in your local Maven repository. We need to get the artifact in the Jenkins workspace directory. For that, we use mvn dependency:copy, which copies the artifact from your local repository into a workspace folder, target/dependency by default.

Finally, we’re going to issue the JBoss AS/EAP command line utility (“CLI”) to run the deployment. One interesting wrinkle to notice is that you have to add the –server-groups flag within the quotes for your command. I couldn’t find this neatly documented anywhere, so I hope it saves you a little time.

Interesting. But what can we do to improve it?

With the solution I proposed, anyone with a password could deploy any artifact anywhere. In reality, you’d want to tighten this down eventually by hard coding some of the values and controlling access to “who can deploy to what” environment, likely with the build pipeline (or similar) Jenkins plugin.

Unfortunately, even though I configured the as_password as a password field, for some reason it continues to display the clear text password in the log files. This is probably fixable so it will print a “masked” version of the password.

I created a little demo project along with the script in a Github repo, jboss-cli-deploy.

A simple message driven bean (MDB) in JBoss AS/EAP with Maven

I had a really hard time finding a really simple example to show, so hopefully this will help you.

How to Set Up Your Maven Project

Sometimes I swear that getting a Maven project is sometimes the hardest part of getting a Java EE project going. Once you’ve got it, it all snaps into place. Here’s a simple pom:

Create a Message Driven Bean (MDB)

Here’s a simple example:

Now Create a Client to Send Messages Into the Queue

This too is pretty straightforward. In my example, I just run it with a servlet.

Now Configure JBoss AS 7 / EAP 6

You’ll need to start AS/EAP in at least standalone-full mode because the simple standalone configuration — out of the box — does not start the HornetQ queueing system:

Finally add the queue to AS/EAP. You can use the JBoss CLI (, with this command:

How to develop a custom module for JBoss EAP 6x / AS 7

Sometimes you want to be able to share a custom JBoss EAP module across a number of different WARs or EARs on your application server. I cam across this recently when a client had a big module that retrieved a lot of data from a legacy system. Since the data set was so big, it didn’t make sense to deploy the library with every application.

There are really just two steps to the process: build the custom module and then wire up your application to use it.

Step one: create a custom JBoss module

Developing the custom module

If you’re using JBoss AS7 or EAP 6x, you’re probably using Maven. So here’s a pretty minimal pom to get you started. The only real dependency you might want to exclude (but do you really?!?) is Google’s Guava.

Now, let’s do the test driven development thing and start with a test class in the src/test/java Maven directory. If you haven’t worked with this approach with Intellij IDEA, you’re missing out. The ergonomics really are nice.

And here’s the actual implementation class:

Now, let’s assemble the module. Remember how I included the Guava package? Well, to make this demo simple, let’s go ahead and rely on the maven-assembly-plugin that we included in the pom above like this.

First, run mvn clean package, and you’ll see two different artifacts created:


Installing the custom JBoss module

Now let’s get the module installed. First, create a directory named {jboss_home}/modules/com/redhat/demo/main. The “main” is significant because it lets you configure multiple “slots” if you have different versions of the same module installed on the server. Then copy the JAR file with the dependencies over to that main directory.

Next, we’ll create a descriptor in that “main” directory called module.xml. Mine is ultra simple with the following:

Finally, let’s set up the module as a “global” module so it’s easily available to all the application on AS7/EAP 6 by adding the following to standalone.xml (or the equivalent in domain.xml):

Now start your JBoss AS7/EAP instance.

Step two: start using the module

I created a simple “hello, world” type servlet just to demo the module. Here’s the pom:

And here’s the simple servlet:

That’s it, now deploy it on your instance and you should see it running.

JNDI string bindings vs external properties files

It’s pretty common to have a web application depending on server side properties. An obvious example is when you want the app to connect to a database connection depending on whether the app is on a development server or a production server.

I’ve worked on apps that store those properties in external properties files (accessed via the classpath) as well as apps that store the values in string-based JNDI bindings.

My question is which approach is better. On the one hand, the properties file lets me feel like I’m developing an app that’s very independent of the server technology. Also, it feels abusive to use the sophisticated JNDI technology to get a simple string.

But the thing I really like about JNDI is that the application can fail fast on deployment if the binding hasn’t been configured.