-
Notifications
You must be signed in to change notification settings - Fork 332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: SpringBoot3 - Unable to load Context #869
Comments
Hi there, I've done some tests and investigations on that topic. Changing all references from javax.servlet to Jakarta.servlet is not the major problem, even if some deprecated methods does not exist anymore. Some minor changes were also needed in makefile / autoconf to split classpath and modulepath, The major issue I encountered is that sometimes, when I call PUT rest endpoint to load my application war, I have to kill the "prototype" and "application" process, Changes made : Many TODOs to resolve around WebSocket and Multipart best regards. |
@gdufrene that branch looks fantastic; are you planning to continue working on it and propose a pull request here? We'd gladly review it or try to assist in debugging. |
Hello @callahad , Sure I can help around this issue and continue working on it, time to time. There is some questions around nginx-unit support for java EE vs jakarta EE. Maybe 2 different module will be a better fit :
I think it will fit support for major frameworks such as spring and sprint-boot. So, on the other hand, Let me know what you think. A last few words about the "native" approach. |
@gdufrene Right now, the Java language support in Unit is largely community driven; the folks we have working on Unit itself aren't especially familiar with Java in the wild. My gut is that supporting Spring Boot 3 (and thus Jakarta EE / Java 17) is the right way to go for an open source project. However, we suspect that there are users of Unit relying on Java EE... We'd welcome your recommendations for what would be most useful as a consumer of the Java language support. |
Hi @gdufrene The normal way we handle support for different versions of language stack in the language modules is via a bunch of #ifdefs... see src/nxt_php_sapi.c and src/python for examples. I see from your current changes you are really just changing the code under src/java/nginx (as well as the java build infra), the C code under src/java seems isolated from these changes. My gut feeling is while #ifdefs may not be the way to go here, also I feel an entirely separate module may be overkill (at the source level). It seems like we really need to re-factor the current java module (and this is entirely off the top of my head after 5 minutes looking at it) the we should split the module up into three components
Then when configuring the java module you could specify a --target= (or whatever name) for either javax or jakarta... You would be able to do this for each target to get two actual modules if you needed to support both... Probably some details to figure out like module naming, e.g java.javax.unit.so/java.jakarta.unit.so and then types of java-javax/java-jakarta in the unit config, something like that... How does that sound? |
Hello, 3 components as you describe seems me a good idea. Right now, It's not really clear for me how to use autoconf to specify a target (javax/jakarta) but I will take a look. About the module naming, including java version could be an option, as described in how-to / configuring modules / java documentation page. I will try to work on it that way, thanks for your comments. |
Right, once we have the two things working we can see what common code can be factored out. We'll already have the C code under src/java as common code...
Not autoconf as such, but a home grown build system.
My current thinking is that we would have
I'm here to give any assistance I can... |
Hello @ac000 I updated my branch with a "work in progress" solution. When working on it, I realize that most of dependencies between C code and java are method and class references. The runtime impacts are embedded in the compiled java code packaged as "nginx-unit-jsc-java-$version.jar" Right now, I created two directories inside src/java :
Both are defined as maven project to help with dependencies, versions, compilation. I try to update auto/modules/java to handle a "target" argument (default to javax) to build the module with the correct dependencies. A lot more things to do, but it seems me quite promising. With my current environment I still often get some trouble in loading an application config with the java module. |
HI, Sounds like you're making good progress!
If you think this is the best way to go, I'm happy to defer to you on that. Will we still be able to target different version of java? As I know we do build various versions of the java language module for different versions of java...
Hmm, this is not an issue I've been aware of and we do have pytests covering java and I haven't seen an issue with them...
Are you using FreeBSD? |
Yes, you can target a specified version of jvm with already defined configure module option "-home"
I'm using a mac with Homebrew to get building tools Maybe I can try in a docker container or try with an other kind of module to check if I have the same issue occurs. |
OK, cool. I haven't actually looked at how we currently do it...
Hmm..
Actually, I have my F5 intel mac I could try on... If you install pytest, then if you've built unit and the java language module, no need to install them, you can then do |
On my current branch with jakarta / java17 all tests fails. I switch back on master branch and try to run a first test with java17 runtime on "javax.servlet" expected code. With an openjdk 8 for my system (Zulu for its support of arm64), it works and all tests green (except skipped one for normal reasons). Maybe I should first focus on why there is some differences between runtimes and find a way to work with java 17 on javax.servlet spec.
when I compile java module with java 17, this warning triggered :
that's why I suspect a security thing, even if the code seems to be specific to the websocket support. Some security changes on the jvm could be a reason. more investigations to follow. |
Well ... I'm back to a random deadlock hypothesis, due to the javaVM version ? When re-configure application config, the process freeze randomly at least at 2 places :
I'm not really confident on my skills to find and fix that kind of problem :( added some logs in nxt_java.c to track nxt_java_start init steps logs when freeze at createVM
logs when freezing a little bit later avec starting context :
And when it goes well :
|
On
Unit 1.29.1 - Java17 - Docker
eclipse-temurin:17-jdk-jammy
It is not possible to load a SpringBoot application version >=3.0. Unit did not crash. It simply isn't loading the Spring Application context. The log initially shows:
Sending request to the
HelloWorldController
which should answer with a niceHello from Spring on Unit!
is displaying a directory index likeStarting
unitd
in debug mode shows the reason:As Spring >= requires Tomcat10 with Servlet 5 it is not longer compatible with Units Servlet Implementation. Looking at the Changes from Apache Tomcat 8 to 10 shows that they moved from
javax
tojakarta
.It would be necessary to implement a new Servlet Spec to be able to load the Context of the newer generation of Spring Boot applications for example.
Please consider this issue as documentation only - we are not in a hurry to fix this for now. I just wanted to find a place to document my findings.
An application to reproduce is attached.
spring3-0.0.1-SNAPSHOT.war.zip
The unit configuration
The text was updated successfully, but these errors were encountered: