Issue
As you probably know, javax had to change it's name to jakarta due to a trademark issue. Right now my company has gives our customers two .jar files, one for those using Tomcat 9 or earlier (javax) and one for Tomcat 10 (jakarta).
Is it possible to create one jar file that can see which Tomcat is used and for every import choose either javax or jakarta? This project does not use Spring.
I already found how to tell which Tomcat version is used.
I see JAVA does not have preprocessor directives like C++. Is there something similar that will allow me to swap the imports?
I also see that I don't have to use imports and just call the class using the whole path. This seems like a lot of work, but a possible solution. I just want to know if there is a quicker easier solution.
Solution
The behavior you describe can be achieved with a ClassFileTransformer
like the one provided by the Tomcat Migration Tool. Every copy of Tomcat 10 is bundled with the shaded version of the migration tool, so you don't need to distribute it independently.
You can create a jakarta.servlet.ServletContainerInitializer
which will inject the ClassFileTransformer
upon the web application startup:
import java.util.Set;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import org.apache.tomcat.InstrumentableClassLoader;
import org.apache.tomcat.jakartaee.ClassConverter;
public class JavaEEContainerInitializer implements javax.servlet.ServletContainerInitializer {
@Override
public void onStartup(Set<Class< ? >> c, ServletContext ctx) throws ServletException {
final ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl instanceof InstrumentableClassLoader) {
final InstrumentableClassLoader instrumentableCl = (InstrumentableClassLoader) cl;
instrumentableCl.addTransformer(new ClassConverter());
}
}
}
However in the case of a library I would rather distribute two versions of it, so the library does not have to mess with the class loader of the application. E.g. openwebbeans
provides two versions of the same artifact: a Java EE version and a Jakarta EE version with the jakarta
classifier.
The aforementioned Tomcat Migration Tool can automatically generate the Jakarta EE version of the jar.
Answered By - Piotr P. Karwasz