-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8349178: runtime/jni/atExit/TestAtExit.java should be supported on static JDK #23431
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
Conversation
…ink with libjvm for libatExit. - Lookup JNI_GetDefaultJavaVMInitArgs, JNI_GetCreatedJavaVMs and JNI_CreateJavaVM from the VM. Replace direct calls with calls using the retrieved function addresses.
|
👋 Welcome back jiangli! A progress list of the required criteria for merging this PR into |
|
@jianglizhou This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 78 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
|
@jianglizhou The following labels will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command. |
|
@jianglizhou I will be brutally honest and say that I do not like this at all. Does this mean all JNI using tests/applications have to becoded differently to be used with a static JDK? I find it somewhat ironic that to work with a static JDK we have to rewrite the test to perform a dynamic lookup! |
@dholmes-ora Thanks for the forthright response. JNI functions are already dynamically called. E.g. in the same test here: We don't need to change those at all to work on static-jdk. The existing design of JNI functions can work on both dynamic JDK and static JDK. The calls fixed by this PR are the very few exceptions that do not follow the design principle. I do think we should fix them by following the right patterns/conventions. Note
So far I've only found this test in hotspot tier1 and libExplicitAttach (AttachTest_id0) in JDK tier1 with the issue. @dholmes-ora If we don't go this change, do you have any other suggestion? One other possible alternative that I can think is using weak symbols, however I think that's no better. |
|
Also to point it out if it's not clear already, |
A custom launcher will typically link to libjvm or use dlopen/dlym to get to JNI_CreateJavaVM. A static build isn't really suitable for custom launchers (or anything that embeds a VM). So I think the changes to the test are okay if we really want to run this test with a static build. An alternative is to have the tests that use JNI_CreateJavaVM to not be selected. At some point I suspect we'll need to add a property to jtreg-ext/requires/VMProps.java for these builds anyway. |
Just want to provide some relevant data point. We build custom launcher and statically link with the libjvm (for hermetic case). If libjvm is statically linked with the launcher, then there's actually no need to change the direct calls to those JNI_ functions. The direct calls are not problematic on static build.
The alternative also sounds reasonable to me. We could skip running on static JDK if a test explicitly requires libjvm.so, libjava.so, etc at runtime, at least initially.
That's a good point. We can add a |
|
Thanks for clarifying @jianglizhou . Okay so the issue is only with the top-level invocation API functions:
|
Is there any other example? Presuming the existence of dynamic linked libraries is pretty standard. |
|
I want to answer the question carefully to avoid possible confusions, so the comment below may provide extra information (also verbose) than just addressing the question. Please let me know if anything is unclear.
Yes. A launcher executable can explicitly link with a native library, either using .so (shared library) or .a (static library) if the launcher code has any direct references to symbols defined in the native library. The launcher can also choose to do dynamic symbol lookup and avoids the need for explicitly linking with the native library. If a launcher executable is linked with libjvm.so at build time, it requires libjvm.so to be resolved (normally from the RPATH) and loaded successfully when the launcher executable is loaded. Otherwise the executable fails to load and start due to the missing libjvm.so dependency. If a launcher executable is statically linked with libjvm.a, runtime does not try to find the libjvm.a since that is already built into the executable. Same for a shared library (e.g. the libatExit.so used by the test) linked with libjvm.so, the shared library fails to be loaded if libjvm.so do not present at runtime. If launcher code choose to use dynamic symbol lookup and avoids linking with libjvm.so, the launcher code can support both dynamic case and static case. The
Yeah, since there are just few cases in the tests, I feel fixing these tests seem to be a good choice. |
Other possible examples could be running the test on different JVM implementation (e.g. non-hotspot) that does not have libjvm.so. |
|
@dholmes-ora and @AlanBateman Could you please review and approve the change if there's no additional concerns? I also sent out #23500, which applies the same principle to fix libExplicitAttach issue. I'm also in the process of adding the VMProps for static JDK as @AlanBateman suggested. That's needed to skip the tests require accessing tools in |
|
@AlanBateman I created #23528 for the VMProps change. Thanks. |
dholmes-ora
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay - approved.
|
Thanks, @dholmes-ora! |
|
/integrate |
|
Going to push as commit 84b32cb.
Your commit was automatically rebased without conflicts. |
|
@jianglizhou Pushed as commit 84b32cb. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Please review runtime/jni/atExit/TestAtExit.java test change:
BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libatExit := java.base:libjvm. Don't explicitly link with libjvm, because it adds libjvm.so as a recorded dependency to libatExit.so (on Linux for example). That requires libjvm.so must be resolved and loaded successfully when libatExit.so is loaded. The static JDK (e.g. static-jdk image) does not provide a libjvm.so for runtime usage.On Linux (and similar) platform, there is no need to call
dlopenfor libjvm in libatExit.c explicitly, because the VM must already be loaded by the time when the libatExit native code is executed. UsingRTLD_DEFAULTcan "find symbols in the executable and its dependencies, as well as symbols in shared objects that were dynamically loaded with the RTLD_GLOBAL flag" (see https://man7.org/linux/man-pages/man3/dlsym.3.html).jdk/src/java.base/unix/native/libjli/java_md.c
Line 533 in 9b49597
dlopenlibjvm withRTLD_GLOBALfor unix platform.For Windows platform, I added Windows specific code to get the loaded
jvm.dllfirst. If it can't find loadedjvm.dll, it then get the handle of the executable running the current process. The returned handle is used for finding the function addresses.TestAtExit passes with https://github.com/jianglizhou/jdk/actions/runs/13124407248/job/36619759000. TestAtExit also pass on static-jdk with my local jtreg run.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/23431/head:pull/23431$ git checkout pull/23431Update a local copy of the PR:
$ git checkout pull/23431$ git pull https://git.openjdk.org/jdk.git pull/23431/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 23431View PR using the GUI difftool:
$ git pr show -t 23431Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/23431.diff
Using Webrev
Link to Webrev Comment