Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:


NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

We saw in a previous article how Spring Remoting could be used to provide RPC on top of an asynchronous channel as an AMQP queue. However, we can obtain the same result using JMS too.

In this article, we'll, in fact, explore how to set up remote invocation using Spring Remoting JMS and Apache ActiveMQ as a messaging middleware.

2. Starting an Apache ActiveMQ Broker

Apache ActiveMQ is an open source message broker that enables applications to exchange information asynchronously, and it is entirely compatible with the Java Message Service API.

To run our experiment, we firstly need to set up a running instance of ActiveMQ. We can choose among several ways: following the steps described in the official guide, embedding it in a Java application or more simply spinning up a Docker container with the following command:

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3

This will start an ActiveMQ container that exposes on port 8081 a simple administration web GUI, through which we can check the available queues, connected clients, and other administrative information. JMS clients will need to use port 61616 to connect to the broker and exchange messages instead.

3. Maven Dependencies

As in the previous articles covering Spring Remoting, we are going to set up a server and a client Spring Boot applications to show how JMS Remoting works.

As usually we carefully choose the Spring Boot starter dependencies, as explained here:


We explicitly excluded the spring-boot-starter-tomcat in order not to have the Tomcat related .jar files in the classpath.

This, in turn, will prevent the Spring Boot‘s autoconfiguration mechanism to launch an embedded web server when the application starts up since we don't need it.

4. Server Application

4.1. Expose the Service

We'll set up a server application that exposes the CabBookingService that clients will be able to invoke.

The first step is to declare a bean that implements the interface of the service we want to expose to the clients. This is the bean that will execute the business logic on the server:

CabBookingService bookingService() {
    return new CabBookingServiceImpl();

Let's then define the queue from which the server will retrieve invocations, specifying its name in the constructor:

Queue queue() {
    return new ActiveMQQueue("remotingQueue");

As we already know from the previous articles, one of the main concepts of Spring Remoting is the Service Exporter, the component that collects the invocation requests from some source, in this case, an ApacheMQ queue ─ and invokes the desired method on the service implementation.

To work with JMS, we define a JmsInvokerServiceExporter:

JmsInvokerServiceExporter exporter(CabBookingService implementation) {
    JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
    return exporter;

Finally, we need to define a listener that has the responsibility to consume messages. The listener acts as a bridge between ApacheMQ and the JmsInvokerServiceExporter, it listens to invocation messages available on the queue, forwards the invocation to the service exporter and serializes back the results:

@Bean SimpleMessageListenerContainer listener(
  ConnectionFactory factory, 
  JmsInvokerServiceExporter exporter) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    return container;

4.2. Configuration

Let's remember to set up the application.properties file to allow Spring Boot to configure some basic objects, as for instance the ConnectionFactory needed by the listener. The values of the various parameters mainly depend on the way

The values of the various parameters mainly depend on the way ApacheMQ has been installed, and the following one is a reasonable configuration for our Docker container running on the same machine where we'll run these examples:


The spring.activemq.broker-url parameter is a reference to the AMQ port. A deeper explanation is needed for spring.activemq.packages.trusted parameter instead. Since version 5.12.2 ActiveMQ refuses by default any message of type

Starting with version 5.12.2 ActiveMQ refuses by default any message of type ObjectMessage, used to exchange serialized Java object because it is considered a potential vector for a security attack in some contexts.

Anyhow, it is possible to instruct AMQ to accept serialized objects in specified packages. org.springframework.remoting.support is the package that contains the main messages that represent the invocation of a remote method and its result. The package

The package com.baeldung.api contains the parameters and the results of our service. java.lang is added because the object that represents the result of the cab booking references a String, so we need to serialize that too.

5. Client Application

5.1. Invoke the Remote Service

Let's tackle the client now. Again, we need to define the queue where invocation messages will be written to. We need to double-check that both client and server use the same name.

Queue queue() {
    return new ActiveMQQueue("remotingQueue");

We then need to set up an exporter:

FactoryBean invoker(ConnectionFactory factory, Queue queue) {
    JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean();
    return factoryBean;

We can now use the remote service as if it was declared as a local bean:

CabBookingService service = context.getBean(CabBookingService.class);
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));

5.2. Run the Example

Also for the client application, we have to choose the values in the application properly.properties file. In a common setup, those would exactly match the ones used on the server side.

This should be enough to demonstrate the remote invocation through Apache AMQ. So, let's first start ApacheMQ, then the server application, and finally the client application that will invoke the remote service.

6. Conclusion

In this quick tutorial, we saw how we could use Spring Remoting to provide RPC on top of a JMS system as AMQ.

Spring Remoting keeps on demonstrating how it is easy to set up asynchronous call regardless of the underlying channel quickly.

As usual, you’ll find the sources over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:


Generic footer banner
Comments are closed on this article!