DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Alternative Structured Concurrency
  • Optimizing Java Applications for Arm64 in the Cloud
  • 1-Line IO in Java
  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java

Trending

  • Building a Production-Ready AI Agent in 2026: Beyond the Hello World Demo
  • AI Paradigm Shift: Analytics Without SQL
  • AI-Driven Integration in Large-Scale Agile Environments
  • How Reactive Scaling Drains Your Cloud Budget Without Warning
  1. DZone
  2. Coding
  3. Java
  4. Converting ActiveMQ to Jakarta (Part III: Final)

Converting ActiveMQ to Jakarta (Part III: Final)

This is the final blog post in a series covering the conversion of Apache ActiveMQ to Jakarta EE and JDK 17 to share best practices with enterprise software developers.

By 
Matt Pavlovich user avatar
Matt Pavlovich
·
Oct. 08, 25 · Analysis
Likes (0)
Comment
Save
Tweet
Share
2.3K Views

Join the DZone community and get the full member experience.

Join For Free

Advanced Technical Approach

Some Java frameworks have taken on the complexity of supporting both javax and jakarta package namespaces simultaneously. This approach makes sense for frameworks and platform services, such as Jetty and ActiveMQ, where the core development team needs to move the code base forward to support newer JDKs, while also providing a way for application developers to adopt Jakarta EE gradually. This simplifies the support for open-source frameworks, as there are fewer releases to manage, and in the event of a security bug, being able to release one mainline branch vs having to go back and backport across past versions.  

However, supporting both javax and jakarta namespaces simultaneously in a single application is complicated and time-consuming. Additionally, it opens additional scenarios that may lead to errors and security gaps for enterprise applications. This limits the ability to set up verification checks and source code scanning to block pre-Jakarta libraries from being used or accidentally pulled in through transitive dependencies. It creates a lot of ambiguity and reduces the effectiveness of DevOps teams in providing pre-approved SDKs to be used by enterprise developers. With the pitfalls outweighing the benefits, enterprise projects should not need to support both javax and jakarta namespaces simultaneously in most scenarios.

Special Consideration for Exception Handling for Remote Operations

The one caveat to this best practice for enterprise applications is that there may be a need to support mapping exceptions between javax and jakarta package namespaces to support clients making remote calls to a service or API. The server-side either needs to be able to detect javax clients and translate, or a thin client-side wrapper is needed to handle any jakarta exceptions received by remote services. Apache ActiveMQ handles exception namespace mapping appropriately for all client release streams (starting with v6.1.0, v5.19.0, v5.18.4, v5.17.7, and v5.16.8), so no additional handling is required by applications when using Jakarta Messaging.

Jakarta EE Updates and Nothing Else

A key factor to ActiveMQ’s success was that the scope of change was limited to only what was necessary for the upgrade to Jakarta EE. The change of underlying frameworks naturally brought new minimum JDK version requirements and other changes, as Jakarta EE specifications brought forward their own set of changes.

No protocol changes, no data format, or configuration changes were made to ActiveMQ to support backwards compatibility with javax clients and to support roll-forward and rollback during upgrades.

Developers should resist the urge to tackle other refactoring, data model, or business functionality changes when making the upgrade to Jakarta EE. These upgrades should be structured as technical debt-only releases to ensure the best outcomes.

Jakarta Migration Planning Guide

Team Impact: Organizing Changes for Code Review

For an enterprise taking on a similar migration of a large and established code base, I highly recommend following this next piece of advice to lower the time and level of effort.

Enforce an organizational policy that requires git commits related to package naming to be separated. There should be two types that are clearly labeled in the comments:

  1. Java package import namespace-only changes
  2. Code changes

Namespace-only changes involve updating the file from “import javax.” to “import jakarta.” These text changes may live in Java code files, Spring XML, config properties, or other non-Java code artifacts used by the application.

Code changes are updates required due to fixes, technical debt, supporting Jakarta EE specification changes, or framework API changes (such as Spring or Jetty).

By separating these changes, you will greatly reduce the time required to review and approve changes. Java package namespace-only changes will have hundreds to thousands of files changed, and thousands to tens of thousands of lines changed. For the most part, these changes can be approved quickly, without the need for a deep code review.

The actual impacting code changes should impact fewer files and fewer lines of code change. The code reviews on these changes will require a closer look, and by reducing the scope, you will greatly reduce the time required for code reviews.

Practical Tips for Jakarta Migration

  1. Drop end-of-life and deprecated modules from your code base.
  2. Migrate or drop end-of-life and deprecated dependencies.
  3. Upgrade code to use in-Java features where commons-* dependencies are no longer needed.
  4. Upgrade to current non-Jakarta affecting dependencies you may have been putting off (Log4j v2, JUnit v5, etc.).
  5. Where possible, release JDK 17 changes first (Upgrade JDK using LTS versions 8 -> 11 -> 17).
  6. Release a tech-debt update of your product or application. This allows for supporting two modern release streams—non-Jakarta and Jakarta.
  7. Update frameworks to Jakarta EE versions.
  8. Break-up commits to have import-only changes for faster review.
  9. For complex in-house ‘framework’ type components, consider releasing support for both javax and jakarta at the same time.
  10. Add support for client-side Jakarta EE module alongside existing modules in the javax release stream.
  11. Break-up commits to have import-only changes for faster reviews.

In Summary

Apache ActiveMQ was successful in its migration to Jakarta EE by tackling necessary technical debt and putting off the urge to incorporate too many changes. The transition was successful, and users were able to quickly adopt the ActiveMQ 6.x releases in their Jakarta EE projects.

Additionally, since the wire protocol, configuration, and data formats did not change, older javax applications (and non-Java applications) were able to work seamlessly through an upgrade.

This is an exciting time for Java developers as the ecosystem is rapidly adopting awesome new features and great language improvements. I’m interested in your feedback as you tackle Jakarta EE and JDK upgrades for projects of all sizes.

Reference Material

change type estimated level of effort
Namespace change from “import javax…” to “import jakarta..” Low
Upgrade to JDK 17 Medium
Update Maven tooling to align with JDK 17 Medium
Update and refactor code to use updated Jakarta specifications APIs Medium
Update and refactor code to use current dependencies that implement updated specification APIs High
Pay down technical debt
High
Update and refactor code to drop any dependencies that are not current with Jakarta, JDK 17 or transitive dependencies
High
Team impacts - Managing change across the enterprise
High


ActiveMQ's Jakarta Migration Metrics

The following statistics are provided as a reference for the level of effort required in migrating a medium-sized, mature Java project to Jakarta EE. 

PRs 1
Commits 25 (the number of intermediate commits is over 100)
Files changed 1,425
Lines added 9,514
Lines removed 8,091
Modules dropped 2* (1 is the transition module, which got a relocation)
Dependencies re-homed 2
Frameworks dropped 2
Deprecated J2EE specifications dropped 1
PR work tasks 28
CI build jobs 80

Apache ActiveMQ 6.0.0 Jakarta Messaging 3.1.0 Release Summary

  1. Permanently dropped module:
    • activemq-partition (drop deprecated Apache ZooKeeper test dependency)
  2. Jakarta APIs:
    • Jakarta Messaging
    • Jakarta XML
    • Jakarta Servlet
    • Jakarta Transaction
  3. Upgrade key dependencies:
    • Jetty v11
    • Spring v6
    • Java JDK 17+
    • Maven modules
  4. Drop JEE API specs that do not have a Jakarta version:
    • j2ee-management (interfaces re-implemented locally to Apache ActiveMQ)
  5. Re-homed test dependencies:
    • stompjms Java STOMP client
    • joram-jms-tests JMS test utilities
  6. Temporarily dropped dependencies that did not have Jakarta support at the time. Note: Both have been added back in as of ActiveMQ 6.1.x.
    • Jolokia
    • Apache Camel
Apache ActiveMQ Java Development Kit Java (programming language)

Published at DZone with permission of Matt Pavlovich. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Alternative Structured Concurrency
  • Optimizing Java Applications for Arm64 in the Cloud
  • 1-Line IO in Java
  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook