Skip to content

Perform the jakarta EE migration#414

Open
ohumbel wants to merge 5 commits intojython:masterfrom
ohumbel:feature/jakartaee
Open

Perform the jakarta EE migration#414
ohumbel wants to merge 5 commits intojython:masterfrom
ohumbel:feature/jakartaee

Conversation

@ohumbel
Copy link

@ohumbel ohumbel commented Feb 4, 2026

The goal is to replace javax.servlet with jakarta.servlet.

Some application containers like WildFly refuse to start up if a .jar file on the classpath contains a class in a package javax.servlet.
This pull request will enable embedding Jython in modern applications.

@Stewori
Copy link
Member

Stewori commented Feb 4, 2026

This is related to issue #382, but does not seem to take the discussion into account (nor reference the issue in the description). As it stands, the fix is not backwards compatible and as a drop-in replacement might break existing setups without warning or deprecation path or anything. At very least, such a change should induce a change in maven coordinates, e.g. to jython-jakarta-standalone etc. Compared to that, I would prefer the solution I suggested in #382. If you see it differently, please explain why the approach should be preferred over the suggested solution.
That said, why would we base this on jakarta-api 9.0? Jakarta 11 is the current release. Given Jython's infrequent releases and the still manual work of adding the dependencies, it should be updated as far as possible. Another question: Why jakarta-api and not jakarta-servlet any more? AFAIK, best practice is to narrow dependencies as far as possible. Jython does not depend on any other Jakarta module. IMO jakarta.servlet-api/6.1.0 would be the correct current depndency as of this writing (6.2.0 is in M1 phase).

@ohumbel
Copy link
Author

ohumbel commented Feb 6, 2026

Why jakarta-api and not jakarta-servlet any more? AFAIK, best practice is to narrow dependencies as far as possible.
Jython does not depend on any other Jakarta module. IMO jakarta.servlet-api/6.1.0 would be the correct current dependency as of this writing (6.2.0 is in M1 phase).

That is correct - jakartaee-api is too broad. I was able to replace it with jakarta.servlet-api-5.0.0.

Newer versions do not compile with java 8.

jakarta.servlet-api-6.1.0:

/jython/src/org/python/util/PyServlet.java:13: error: cannot access jakarta.servlet.ServletContext
import jakarta.servlet.ServletContext;
                      ^
  bad class file: /.gradle/caches/modules-2/files-2.1/jakarta.servlet/jakarta.servlet-api/6.1.0/1169a246913fe3823782af7943e7a103634867c5/jakarta.servlet-api-6.1.0.jar(jakarta/servlet/ServletContext.class)
    class file has wrong version 55.0, should be 52.0

jakarta.servlet-api-6.0.0:

/jython/src/org/python/util/PyServlet.java:13: error: cannot access jakarta.servlet.ServletContext
import jakarta.servlet.ServletContext;
                      ^
  bad class file: /.gradle/caches/modules-2/files-2.1/jakarta.servlet/jakarta.servlet-api/6.0.0/abecc699286e65035ebba9844c03931357a6a963/jakarta.servlet-api-6.0.0.jar(jakarta/servlet/ServletContext.class)
    class file has wrong version 55.0, should be 52.0

Since Jython targets java 8, there is only a narrow range of external libraries which can be used. I suspect that this range will get even more narrow with the progress of the java ecosystem.

@ohumbel
Copy link
Author

ohumbel commented Feb 6, 2026

That said, why would we base this on jakarta-api 9.0? Jakarta 11 is the current release. Given Jython's infrequent releases and the still manual work of adding the dependencies, it should be updated as far as possible.

I would love to offer newer versions of external libraries. But the situation is likely the same as the one for jakarta.servlet-api: Recent versions require a higher version of java.

@ohumbel
Copy link
Author

ohumbel commented Feb 6, 2026

This is related to issue #382, but does not seem to take the discussion into account (nor reference the issue in the description).

I really forgot to reference the issue #382. That is my fault, sorry for that.

Please let me explain in a following comment why I think the solutions suggested in #382 are not workable. I need some time to express this the right way.

@Stewori
Copy link
Member

Stewori commented Feb 6, 2026

Alright, thank you for addressing this. I am not sure whether Jython does actually still support Java 8. I vaguely remember that @jeff5 once mentioned the support was dropped. (I used to feel that we should be more explicit about these decisions, but it turned out to be tedious to keep track.) In that case, a newer jakarta.servlet version might be feasible.

@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

Alright, thank you for addressing this. I am not sure whether Jython does actually still support Java 8. I vaguely remember that @jeff5 once mentioned the support was dropped. (I used to feel that we should be more explicit about these decisions, but it turned out to be tedious to keep track.) In that case, a newer jakarta.servlet version might be feasible.

The build files are explicit:

build.gradle
65: sourceCompatibility = '1.8'
66: targetCompatibility = '1.8'

build.xml
94:      <property name="jython.java.version" value="1.8" />
95:      <property name="jdk.source.version" value="1.8" />
309:     <property name="jdk.target.version" value="${jython.java.version}" />
310:     <property name="jdk.source.version" value="${jython.java.version}" />

@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

As it stands, the fix is not backwards compatible and as a drop-in replacement might break existing setups without warning or deprecation path or anything.

Maybe it is worth mentioning that the latest released Jython version prevents users from upgrading their own projects to jakarta.
The jakarta community decided to do a breaking change instead of a long period of suffering between versions. This decision was made some years ago, and the community has moved forward since then.
I am convinced that there is no other way than breaking backwards compatibility (to a serlvet version that is not maintained any more since years...).

At very least, such a change should induce a change in maven coordinates, e.g. to jython-jakarta-standalone etc. Compared to that, I would prefer the solution I suggested in #382. If you see it differently, please explain why the approach should be preferred over the suggested solution.

The example of WildFly makes it clear that there can be no hybrid solution (WildFly does not start if there is a reference to the old javax.servlet package on the classpath).
The only solution can be two different artefacts, one supporting the old world, one the new.
I still am in favour of Jython 2.7.(n) still supporting the old javax.servlet, and Jython 2.7.(n+1) supporting javax.servlet. Here they are, the above mentioned two artefacts.
I think the maintenance burden of supporting two different artefacts at the same time is much too high. At least I am not willing to dedicate my time to a very, very old servlet version.

Given Jython's infrequent releases, this burns down to a documentation issue.

That are my thoughts, directed to the future. Of course I know - and respect - that one could see it differently.

@Stewori
Copy link
Member

Stewori commented Feb 17, 2026

Okay, thank you for the explanation. I did not know that WildFly blocks startup in this manner (and then, it's the norm for other frameworks too). In that light, I'd suggest the following: Do it like it currently stands, but relocate org.python.util.PyServlet, org.python.util.PyFilter and org.python.util.PyServletInitializer to a new package org.python.servlet. That should work fine and should not be asked too much. It would use the occasion to declutter the org.python.util package and we have the option to offer a separate back-compatibility artifact consisting just of the old org.python.util.PyServlet, org.python.util.PyFilter and org.python.util.PyServletInitializer. Someone could include this artifact on top without name conflict since the packages were adjusted. An old javax.servlet-based WildFly would not break if jakarta.servlet is referenced I suppose. So, this relocation may allow to restore workability of a new Jython release as a drop-in replacement for an old setup by adding a potential backwards artifact on top. I'm not asking to actually provide the backwards artifact, perhaps we actually won't. I just ask to keep that door open by relocating the servlet classes (to a package name that would have been more suitable than plainly util in the first place).

@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

relocate org.python.util.PyServlet, org.python.util.PyFilter and org.python.util.PyServletInitializer to a new package org.python.servlet.

That's perfectly fine - I start working on this (converting this PR to a draft meanwhile)

@ohumbel ohumbel marked this pull request as draft February 17, 2026 15:31
@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

An old javax.servlet-based WildFly would not break if jakarta.servlet is referenced I suppose.

I did not test that, but I am quite convinced that an old WildFly has no knowledge about the later meaning of jakarta.servlet.

So, this relocation may allow to restore workability of a new Jython release as a drop-in replacement for an old setup by adding a potential backwards artifact on top

Exactly, that could be done. But I really hope that this won't be necessary.

…servlet

Adjust the inline documentation accordingly.
@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

Before I push, I use to run the gradle build and the regrtest-ci ant target in a shell with java 8:

➜  jython git:(feature/jakartaee) ✗ sdk use java 8.0.482-tem 
Using java version 8.0.482-tem in this shell.

➜  jython git:(feature/jakartaee) ✗ ./gradlew build
:
:
BUILD SUCCESSFUL in 36s
13 actionable tasks: 7 executed, 6 up-to-date

➜  jython git:(feature/jakartaee) ✗ ant -noinput -buildfile build.xml regrtest-ci
:
:
     [exec] 383 tests OK.
     [exec] 2 tests skipped:
     [exec]     test_codecmaps_hk test_curses

regrtest-windows-ci:

regrtest-ci:

BUILD SUCCESSFUL
Total time: 18 minutes 8 seconds
➜  jython git:(feature/jakartaee) ✗ 

This is on an Intel Macbook pro running macOS Tahoe 26.3.
On ubuntu, the results are comparable.
On windows, I do not know.

@ohumbel
Copy link
Author

ohumbel commented Feb 17, 2026

Your second comment about Java 8 only appeared in my inbox.
I quote it here for completeness:

Re Java 8: I suspect, 65: sourceCompatibility = '1.8' / 66: targetCompatibility = '1.8' were just forgotten. It's well possible that Jython does actually call Java 9 API but keeps class-file format Java 8 compatible. Why? No reason. The real question is whether tests pass on Java 8. If they do (I doubt it), then hooray, it's still Java 8 compatible. I think we removed Java 8 from the CI (because it wasn't offered any more). I currently do not have Java 8 installed so I could test it myself.

Temurin (by Adoptium) still offers Java 8 for all major platforms. On Mac and ubuntu, I use sdkman (https://sdkman.io/install/) to manage all kinds of Java versions.

But I admit that on my company and personal forks, I use to build with Java 21. Which is much faster, by the way.

@ohumbel ohumbel marked this pull request as ready for review February 17, 2026 17:25
@Stewori
Copy link
Member

Stewori commented Feb 17, 2026

I deleted the comment because I checked our CI config and found that Java 8 is indeed still tested. Must have mixed-up the situation with Java 7, sorry for the wrong alert.

@Stewori
Copy link
Member

Stewori commented Feb 17, 2026

Okay, I reviewed the changes again and find that
tests/modjy/java/org/python/util/PyFilterTest.java and tests/modjy/java/org/python/util/PyServletTest.java should consistently be relocated to package org.python.servlet (moving the files from tests/modjy/java/org/python/util to tests/modjy/java/org/python/servlet respectively). Im not familiar with the functioning of test/modjy. Would this relocation need adjustment elsewhere?

@ohumbel
Copy link
Author

ohumbel commented Feb 19, 2026

Okay, I reviewed the changes again and find that
tests/modjy/java/org/python/util/PyFilterTest.java and tests/modjy/java/org/python/util/PyServletTest.java should consistently be relocated to package org.python.servlet (moving the files from tests/modjy/java/org/python/util to tests/modjy/java/org/python/servlet respectively).

Done with the last commit.

Would this relocation need adjustment elsewhere?

Yes, I found references in one other .java file.

Im not familiar with the functioning of test/modjy.

Me neither. I vaguely remember it being "added on top" in the early days...
But I do not think that the tests are alive - I just discovered the separate build.xml and readme.txt. They look quite abandoned to me.

But if they ever would be resurrected, the packages are right.

@Stewori
Copy link
Member

Stewori commented Feb 19, 2026

Note to whoever reads this discussion:
Whenever a binary file is modified I routinely doublecheck that the file is actually the file it is supposed to be. As expected, I can confirm (via cmp) that in this PR the provided jakarta.servlet-api-5.0.0.jar is binary identical to the one distributed at https://repo1.maven.org/maven2/jakarta/servlet/jakarta.servlet-api/5.0.0

@Stewori
Copy link
Member

Stewori commented Feb 19, 2026

Perfect, tests pass, changes look good, we're ready to go. Since the next release is not scheduled, I think we have time to let this PR rest for a couple of days before merging, so other devs have a final chance to intervene if there are any concerns (@jeff5 @wfouche @tbpassin). (This is just another safety measure for me since I haven't pushed the merge button on Jython for a while.) If nobody speaks up, I will merge it on next Wednesday/Feb 25th.
@ohumbel Thank you for the work on this on for your patience!

@tbpassin
Copy link

Your second comment about Java 8 only appeared in my inbox. I quote it here for completeness:

Re Java 8: I suspect, 65: sourceCompatibility = '1.8' / 66: targetCompatibility = '1.8' were just forgotten. It's well possible that Jython does actually call Java 9 API but keeps class-file format Java 8 compatible. Why? No reason. The real question is whether tests pass on Java 8. If they do (I doubt it), then hooray, it's still Java 8 compatible. I think we removed Java 8 from the CI (because it wasn't offered any more). I currently do not have Java 8 installed so I could test it myself.

Temurin (by Adoptium) still offers Java 8 for all major platforms. On Mac and ubuntu, I use sdkman (https://sdkman.io/install/) to manage all kinds of Java versions.

But I admit that on my company and personal forks, I use to build with Java 21. Which is much faster, by the way.

Openlogic has a compatible version of JDK 8+. I was able to build the 2.7.4 version with it. At java 9 and above, there are apparently some changes with how call arguments are handled that caused the build to succeed but the Jython jar file to fail to run in my Tomcat webapp.

@tbpassin
Copy link

Tomcat 9, 10, 11 weren't compiled with the same version of Java. V9 has remained with java 8, but Tomcat v10 is said to have been compiled with java 11; I'm not sure about Tomcat v11. There is also some change in Java v25 that is not always backwards compatible.

Different Linux distros provide different java versions through their package managers. All the version mix-and-match differences can make it hard to make a single Jython jar file work for everyone.

I think that going forward, the minimum Java version should be 17, or even 21. It won't be backwards compatible for some people, say those who are running Tomcat v9 with Java v8. But their systems have already been working and will continue to work as long the Jython 2.7.4 or earlier jar file remains available.

So the easiest approach to the javax/jakarta namespace issue, and the java version issue, seems to be simply to make sure the the current version of the Jython package will continue to be made available along with newer ones.

@Stewori
Copy link
Member

Stewori commented Feb 19, 2026

Issue acknowledged. However, this PR is not the place to address Java version compatibility of Jython as a whole. I think for now it's reasonable to stick to the established compatibility policy. I guess the next release is not too far away and I would not like to break Java 8 compatibility on the last meters. I'd suggest to gradually extend tests to Java 17 and 21, perhaps 25, after Jython 2.7.5 release. Then we'll see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments