Morning all,
I've been struggling lately with the spring-boot-artemis-starter. My understanding of its spring-boot support was the following:
spring.artemis.mode=embedded
and, like tomcat, spring-boot will instanciate a broker reachable through tcp (server mode). The following command should be successful: nc -zv localhost 61616
spring.artmis.mode=native
and spring-boot will only configure the jms template according to the spring.artemis.*
properties (client mode).The client mode works just fine with a standalone artemis server on my machine. Unfortunatelly, I could never manage to reach the tcp port in server mode.
I would be grateful if somebody confirms my understanding of the embedded mode.
Thank you for tour help
After some digging I noted that the implementation provided out of the box by the spring-boot-starter-artemis uses org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory
acceptor. I'm wondering if that's not the root cause (again I'm by no means an expert).
But it appears that there is a way to customize artemis configuration.
Therefore I tried the following configuration without any luck:
@SpringBootApplication
public class MyBroker {
public static void main(String[] args) throws Exception {
SpringApplication.run(MyBroker.class, args);
}
@Autowired
private ArtemisProperties artemisProperties;
@Bean
public ArtemisConfigurationCustomizer artemisConfigurationCustomizer() {
return configuration -> {
try {
configuration.addAcceptorConfiguration("netty", "tcp://localhost:" + artemisProperties.getPort());
} catch (Exception e) {
throw new RuntimeException("Failed to add netty transport acceptor to artemis instance");
}
};
}
}
spring-boot-starter-activemq : It provides all the required dependencies to integrate JMS and activemq with spring boot. activemq-broker : This provides embedded activemq in spring boot application. But since, we will be configuring our activemq outside the application we have commented it for time being.
Apache ActiveMQ Artemis is an asynchronous messaging system, an example of Message Oriented Middleware , we'll just call them messaging systems in the remainder of this book.
spring.artemis.mode has 2 mode: { NATIVE, EMBEDDED }: NATIVE: Connect to a broker using the native Artemis protocol. EMBEDDED: Embed the broker in the application. 2. Sending/Receiving messages For recieved messages, we use: @JmsListener: 3. SpringBoot Artemis applications
When having artemis-jms-client Artemis on the classpath, Spring Boot can auto-configure a ConnectionFactory. spring.artemis.mode has 2 mode: { NATIVE, EMBEDDED }: NATIVE: Connect to a broker using the native Artemis protocol. EMBEDDED: Embed the broker in the application. 2. Sending/Receiving messages For recieved messages, we use: @JmsListener: 3.
Implement Artemis Producer/Consumer For above projects, open application.properties files, add Artemis configuration: 3. Deploy Artemis Go to Artemis download page. Download Artemis 2.1.0: Run the Artemis broker by commnandline: "C:\dev\jsa-springboot-broker\bin\artemis" run
Artemis is the successor of ActiveMQ. So if you’re starting a new project, give it a try. Let’s take a closer look. If you want to learn more about Spring JMS - head on over to the Spring JMS tutorialspage. 1. What is Apache ActiveMQ Artemis? Apache ActiveMQ Artemis a JMS Broker that is based on the HornetQcode base.
My coworker and I had the exact same problem as the documentation on this link (chapter Artemis Support) says nothing about adding an individual ArtemisConfigurationCustomizer - Which is sad because we realized that without this Customizer our Spring Boot App would start and act as if everything was okay but actually it wouldn't do anything.
We also realized that without the Customizer the application.properties file is not beeing loaded so no matter what host or port you mentioned there it would not count.
After adding the Customizer as stated by the two examples it worked without a problem.
Here some results that we figured out:
It only loaded the application.properties after configuring an ArtemisConfigurationCustomizer
You don't need the broker.xml anymore with an embedded spring boot artemis client
Many examples showing the use of Artemis use a "in-vm" protocol while we just wanted to use the netty tcp protocol so we needed to add it into the configuration
For me the most important parameter was pub-sub-domain as I was using topics and not queues. If you are using topics this parameter needs to be set to true or the JMSListener won't read the messages.
See this page: stackoverflow jmslistener-usage-for-publish-subscribe-topic
When using a @JmsListener it uses a DefaultMessageListenerContainer which extends JmsDestinationAccessor which by default has the pubSubDomain set to false. When this property is false it is operating on a queue. If you want to use topics you have to set this properties value to true.
In Application.properties:
spring.jms.pub-sub-domain=true
If anyone is interested in the full example I have uploaded it to my github: https://github.com/CorDharel/SpringBootArtemisServerExample
You just have to add a Connector and an Acceptor to your Artemis Configuration. With Spring Boot Artemis starter Spring creates a Configuration bean which will be used for EmbeddedJMS configuration. You can see this in ArtemisEmbeddedConfigurationFactory class where an InVMAcceptorFactory
will be set for the configuration. You can edit this bean and change Artemis behaviour through custom ArtemisConfigurationCustomizer
bean which will be sucked up by Spring autoconfig and be applied to the Configuration.
An example config class for your Spring Boot application:
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ArtemisConfig implements ArtemisConfigurationCustomizer {
@Override
public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
configuration.addConnectorConfiguration("nettyConnector", new TransportConfiguration(NettyConnectorFactory.class.getName()));
configuration.addAcceptorConfiguration(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
}
}
The embedded mode starts the broker as part of your application. There is no network protocol available with such setup, only InVM calls are allowed. The auto-configuration exposes the necessary pieces you can tune though I am not sure you can actually have a TCP/IP channel with the embedded mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With