Apache ActiveMQ 5.16.3 has been released

Apache ActiveMQ 5.16.3 has been released today. In this blog, I would like to highlights some changes we introduced in this release.

Better Camel 3.x support and JMS2 dependency

I've rewritten the Karaf features repository in ActiveMQ 5.16.3.

Firt, the Karaf features doesn't contain inner repository anymore. The purpose is to let user pickup the version he wants at runtime. Concretely, it means that, in Karaf, ActiveMQ 5.16.3 can already use Spring 5 (fully Spring 5 support including in the ActiveMQ standalone distribution is already done on main branch for ActiveMQ 5.17.x). By the way, I will do similar improvement in Apache CXF and Apache Camel features repositories (removing inner repository to let users pick up at runtime), and Karaf will provides a spec features in a dedicated features repository.

I also updated the range to support JMS 2.x dependency, instead of always forcing JMS 1.x. Even if ActiveMQ 5.16.3 doesn't really support JMS 2, you can already use JMS 2 dependency client artifact if you use only JMS 1 features.

I did similar extend about Camel 3.x. The ActiveMQ Karaf features now supports Camel 3.x (and I also extend the ActiveMQ Camel namespace handler to work with Camel 3.x). It means that you can use ActiveMQ 5.16.3 with Camel 3.x without conflict.

Again, these changes are about the Karaf support.

Include java.util in the allowed package list

In ActiveMQ 5.15.15, we added security enforcement, controlling the packages allowed in the broker for deserialization. This security improvement prevents code injection via derialization. Only java.lang and org.apache.activemq packages were allowed (it could be extended via ACTIVEMQ_ALLOWED_PKGS environment variable). java.util was not included in the default allowed packages list.

Unfortunately, this change had side effect:

  • when using HTTP transport, the XStream marshaller can need java.util package for some messages
  • some broker plugins can be impacted if they use classes from java.util.

Concretely, you are impacted by this issue if you see a trace like this:

  
    java.io.InvalidClassException: Unauthorized deserialization attempt; [Ljava.util.concurrent.ConcurrentHashMap$Segment;
  
  

So, I easily fixed that by adding java.util in the default allowed packages list.

Fix on potential deadlock

ActiveMQ 5.16.3 also fixes couple of potential deadlock on connections.

Taking a threads dump, maybe you noticed in some cases a deadlock looking like:

  
  "ActiveMQ Connection Executor: tcp:///host:61616@51026":
        at org.apache.activemq.SimplePriorityMessageDispatchChannel.close(SimplePriorityMessageDispatchChannel.java:154)
        - waiting to lock 0x0000000773f00308 (a java.lang.Object)
        at org.apache.activemq.ActiveMQMessageConsumer.dispose(ActiveMQMessageConsumer.java:800)
        at org.apache.activemq.ActiveMQSession.dispose(ActiveMQSession.java:689)
        - locked 0x0000000773f003d8 (a org.apache.activemq.ActiveMQSession)
        at org.apache.activemq.ActiveMQConnection.close(ActiveMQConnection.java:659)
        - locked 0x0000000773f99930 (a org.apache.activemq.ActiveMQConnection)
        at org.springframework.jms.connection.SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:456)
        at org.springframework.jms.connection.SingleConnectionFactory.resetConnection(SingleConnectionFactory.java:345)
        - locked 0x0000000773f9a590 (a java.lang.Object)
        at org.springframework.jms.connection.CachingConnectionFactory.resetConnection(CachingConnectionFactory.java:207)
        at org.springframework.jms.connection.SingleConnectionFactory.onException(SingleConnectionFactory.java:323)
        at org.springframework.jms.connection.SingleConnectionFactory$AggregatedExceptionListener.onException(SingleConnectionFactory.java:673)
        - locked 0x0000000773f9a590 (a java.lang.Object)
        at org.apache.activemq.ActiveMQConnection$5.run(ActiveMQConnection.java:1976)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
"privateJmsInPriority.container-1":
        at org.apache.activemq.ActiveMQConnection.getScheduler(ActiveMQConnection.java:2519)
        - waiting to lock 0x0000000773f99930 (a org.apache.activemq.ActiveMQConnection)
        at org.apache.activemq.ActiveMQSession.getScheduler(ActiveMQSession.java:2074)
        at org.apache.activemq.ActiveMQMessageConsumer.rollback(ActiveMQMessageConsumer.java:1241)
        - locked 0x0000000773f01030 (a java.util.LinkedList)
        - locked 0x0000000773f00308 (a java.lang.Object)
        at org.apache.activemq.ActiveMQMessageConsumer$5.afterRollback(ActiveMQMessageConsumer.java:1032)
        at org.apache.activemq.TransactionContext.afterRollback(TransactionContext.java:157)
        at org.apache.activemq.TransactionContext.commit(TransactionContext.java:332)
        at org.apache.activemq.ActiveMQSession.commit(ActiveMQSession.java:561)
        at sun.reflect.GeneratedMethodAccessor897.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386)
        at com.sun.proxy.$Proxy49.commit(Unknown Source)
        at org.springframework.jms.support.JmsUtils.commitIfNecessary(JmsUtils.java:217)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:761)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:665)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:319)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055)
        at java.lang.Thread.run(Thread.java:745)
  

This lock was due to a sycnhronized block in ActiveMQCOnnection. The fix we did is to introduced a synchronizedLock object, instead of locking the whole ActiveMQConnection, removing the deadlock.

Fix XStream deserialization risk in XmlMessageRenderer

ActiveMQ HTTP (web related) transport use XStream to marshal/unmarshal JMS messages. Especially, when you want to display a message, we use XmlMessageRenderer where XStream is used to marshal the message as a XML stream.

Previously, we just created XStream marshaller with:


xstream = new XStream()

Unfortunately, it means that we don't configure any security enforcement here and so, we have potential XStream deserialization risk.

To avoid this, we just use default security enforcement on the XStream instance:


xstream = new XStream();
XStream.setupDefaultSecurity(xstream);

Dependencies updates

As usual in any new ActiveMQ release, we did a bunch of dependency updates:

  • Jackson 2.12.4
  • Jetty 9.4.43.v20210629
  • xstream 1.4.17
  • xbean 4.20
  • commons-io 2.11.0
  • ...

The purpose is to include latest CVE fixes and improvements in our dependencies.

Enjoy!

You can download ActiveMQ 5.16.3 here: https://activemq.apache.org/components/classic/download/.

You can find details about this release on the release page (including Release Notes): https://activemq.apache.org/activemq-5016003-release.

Enjoy!

Now, I will focus on ActiveMQ 5.17.0 (and probably 5.16.4).

Comments

Popular posts from this blog

Quarkus and "meta" extension

Getting started with Apache Karaf Minho

Apache Karaf Minho and OpenTelemetry