How to use Java EE and Jakarta EE dependencies together?
Asked Answered
S

2

14

Is it at all possible to use older Java EE libraries (with javax package) in new Jakarta EE applications (with jakarta package)?

All the APIs would be backwards compatible if it weren't for the trademark issue. Is there any runtime library or build tool available that can get them to work together? Is the only solution to fork old libraries and updated them manually?

I'm in particular looking at the Servlet API, but validation, persistence, webservices and mail may bite me too.

Superordinate answered 26/1, 2022 at 11:6 Comment(3)
you could try using a custom class loader that redirects javax imports to jakarta imports if the jakarta imports exist.Alwin
@dan1stiscrying unfortunately that doesn't solve compile-time issues if you're extending a class in the dependency.Superordinate
Depends on the issues. If the dependency doesn't contain any public interfaces referencing javax types, it might still work. But yes, this isn't an option in most cases. The Eclipse Transformer mentioned by BaliusC is probably your best bet.Alwin
V
10

Eclipse Transformer

You can use the Eclipse Transformer project to transform your older Java EE compatible jar with javax.* imports to a jar using jakarta.* imports.

The transformer takes care of some additional things like renaming constants in configuration files and such. It's a work in progress, but does the job quite well already.

To quote the documentation:

Eclipse Transformer provides tools and runtime components that transform Java binaries, such as individual class files and complete JARs and WARs, mapping changes to Java packages, type names, and related resource names.

While the initial impetus for the project was the Jakarta EE package renaming issue, the scope of the project is broader to support other renaming scenarios. For example, shading.

Vareck answered 29/1, 2022 at 21:39 Comment(3)
It can transform a jar, but provides no way to use that jar in place of the original, with all the original's dependencies.Superordinate
I think that should be possible but how this can be done depends on the build tool.Alwin
You can hack it with maven-shade-plugin promoting transient dependencies. All the duplicate files should be resolved in favour of the transformed version.Superordinate
P
1

Like you mention, the APIs are compatible except for the trademark changes, so one solution is to build wrappers around them that delegate from the new library to the old. Might not always be straightforward, but depending on your use case, it could work.

For example:

public class LegacyServlet implements jakarta.servlet.Servlet {
 
  private final javax.servlet.Servlet delegate;
 
  public LegacyServlet(javax.servlet.Servlet delegate) {
    this.delegate = delegate;
  }
 
  @Override
  public void service(jakarta.servlet.ServletRequest req, jakarta.servlet.ServletResponse resp) {
    delegate.service(new LegacyServletRequest(req), new LegacyServletResponse(resp));
  }
}
Padraig answered 29/1, 2022 at 10:18 Comment(3)
That would be quite a lot of work, though e.g. Lombok can help generating all the methods. You also have to wrap everything in the library that takes or returns a javax object.Superordinate
It's not possible to do this for annotations though, is it?Superordinate
Indeed, it won't work for annotations. If you don't mind me asking, why do you want to do this? Whichever solution you eventually settle for will most likely take more time to implement than just updating the libraries and doing a replace all on the imports to change them from javax to jakarta.Padraig

© 2022 - 2024 — McMap. All rights reserved.