Overview
We've done a lot of good work on WildFly Preview in the last year but as
planning work in Jakarta on EE 10 starts to get underway I hope we can make
a lot more progress, specifically in increasing the number of 'native'
jakarta.* EE 9.1 components' we use. This will allow us to focus on EE 10
dev when the time comes. Ideally by the time WF 26 comes out in the Dec/Jan
timeframe we'll have eliminated the transformation of artifacts that we do
when provisioning a server with the wildfly-preview feature pack, and
instead we'll be using native jakarta artifacts available in maven central
or
repository.jboss.org.
This thread is meant to drive discussion about how to do this. WF devs of
course don't control many projects that provide components, so for those
this discussion would be more informational for the WF subsystem leads who
interact with those communities.
By a 'native jakarta component' I mean one whose compiled artifacts use the
jakarta namespace and otherwise support EE 9.1.
If at all possible it should also provide a matching -sources jar, to help
provide a better debugging experience. This is particularly important for
components against which WildFly users would compile applications.
For artifacts we package in modules that we don't mark with
jboss-api="private" or jboss-api="unsupported", it should also provide
a
matching -javadoc jar.
Priority
More urgent are components against which other WF components compile, where
EE classes are part of the API compiled against. The closer a component is
to the root of a dependency chain, the higher the priority, as having a
native component makes it easier for other components to do their work.
EE API spec forks are not necessarily urgent unless WF itself intends to
use that fork instead of the Eclipse project. (We need to formally resolve
which EE 9+ spec forks WF needs, which is a separate topic. WF Preview is
currently using fewer spec forks than standard WF.)
Approaches
There are a number of approaches a project can follow to produce native
components, each with pros and cons
1) Branching and updating code.
This obviously works, but it comes with a big cost if there will be
continued demand for updates using the javax.* namespace. IMHO it is pretty
likely that there will be continued demand for many components to provide
updates to their javax.* releases.
I had been thinking that during the WF 26 cycle WF itself might follow this
approach, but I'm increasingly thinking we should follow one of the other
approaches.
An issue with this is it means you are compiling, which means you need
jakarta.* components to compile against, which may not be available. If
not you can try Stuart Douglas's optimus project to generate during your
build transformed deps to build against. James Perkins tells me he is
working on something along these lines to add to wildfy-extras/batavia.
2) Adapters
Some components might be able to support both javax and jakarta in the same
code base abstracting away the EE API and providing adapters. Not much to
say about this; you know better if it fits your component.
3) Bytecode transformation with a maven qualifier
Here you update your pom and add a plugin execution that transforms that
maven module's normal javax binary to produce another artifact with a
different qualifier.
The key downside to this is it doesn't produce matching -sources.jar or
-javadoc.jar artifacts. So I don't think it should be our preferred
approach.
Jackson 2.12 did this for a few artifacts, e.g.
https://github.com/FasterXML/jackson-jaxrs-providers/blob/2.12/json/pom.x...
They used the shade plugin. This can also be done using
wildfly-extras/batavia or Eclipse Transfomer directly.
4) New maven module, transform all artifacts
Create a new maven module to pair with your javax-based module. Add
"-jakarta" to the artifactId. Module just has a pom. Pom uses plugins that
call the Eclipse Transformer to transform *all* the artifacts from module
it is paired with (binary jar, -sources.jar, -javadoc.jar)
Narayana did this -- see
https://github.com/jbosstm/narayana/pull/1824/files
Hibernate does this for its 5.5 series. This is a gradle build.
https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core-jakar...
5) New maven module, transform source and build
Create a new maven module to pair with your javax-based module. Add
"-jakarta" to the artifactId. Module just has a pom. Use the Eclipse
Transformer to transform the unzipped source from the javax module, writing
it to generated-sources in the jakarta.* module. Then build the jakarta.*
artifacts from the generated source.
Examples of this:
https://github.com/wildfly/wildfly/pull/14485
https://github.com/jboss/metadata/pull/142
A pro (and con) of this approach is you can also transform src/test and
then run the tests. (A con because it can send you down rabbit holes
getting tests to work. That can reveal things that are good to know though.)
Another con is again this means you are *compiling* which means you may
need jakarta.* deps to compile against.
6) Don't transform
There may be some components that use EE APIs internally but objects don't
leak in or out. A possible example would be JSON where a component might
want to deal with JSON for completely internal purposes, and used EE JSON
for convenience. In theory WF could provide javax JSON via internal modules
and the components using it could skip transformation.
I did a similar thing with H2, which provides some servlet integration
classes that WF does not support. I see no reason to worry about a native
jakarta.servlet H2 so I sent up a PR to disable transformation of it:
https://github.com/wildfly/wildfly/pull/14313
Lots to digest here; discussion is very much welcome.
Best regards,
Brian