RFR: 8339480: Build static-jdk image with a statically linked launcher [v9]
Magnus Ihse Bursie
ihse at openjdk.org
Fri Nov 1 17:14:34 UTC 2024
On Fri, 1 Nov 2024 16:25:59 GMT, Magnus Ihse Bursie <ihse at openjdk.org> wrote:
>> As a prerequisite for Hermetic Java, we need a statically linked `java` launcher. It should behave like the normal, dynamically linked `java` launcher, except that all JDK native libraries should be statically, not dynamically, linked.
>>
>> This patch is the first step towards this goal. It will generate a `static-jdk` image with a statically linked launcher. This launcher is missing several native libs, however, and does therefore not behave like a proper dynamic java. One of the reasons for this is that local symbol hiding in static libraries are not implemented yet, which causes symbol clashes when linking all static libraries together. This will be addressed in an upcoming patch.
>>
>> All changes in the `src` directory are copied from, or inspired by, changes made in [the hermetic-java-runtime branch in Project Leyden](https://github.com/openjdk/leyden/tree/hermetic-java-runtime).
>
> Magnus Ihse Bursie has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 10 commits:
>
> - Merge branch 'master' into static-jdk-image
> - Fix bug in filtering out -Wl,--exclude-libs,ALL
> - Don't hardcode server variant
> - Setup LDFLAGS_STATIC_JDK
> - Update GetJREPath comment and remove unnecessary JLI_IsStaticallyLinked check
> - Add lookup asserts
> - Remove superfluous SRC.
> - Merge branch 'master' into static-jdk-image
> - Makefile changes needed for static-launcher and static-jdk-image targets
> - Incorporate changes from leyden/hermetic-java-runtime that allows running a static launcher
I'm still not sure how or why this goes wrong on Linux (or why it manages to work on macOS!), but at least with this patch I get it to work on Linux:
diff --git a/src/java.base/share/classes/jdk/internal/jimage/NativeImageBuffer.java b/src/java.base/share/classes/jdk/internal/jimage/NativeImageBuffer.java
index 0e3b178c32b..54db79e6527 100644
--- a/src/java.base/share/classes/jdk/internal/jimage/NativeImageBuffer.java
+++ b/src/java.base/share/classes/jdk/internal/jimage/NativeImageBuffer.java
@@ -40,7 +40,7 @@ class NativeImageBuffer {
new java.security.PrivilegedAction<Void>() {
@SuppressWarnings("restricted")
public Void run() {
- System.loadLibrary("jimage");
+ jdk.internal.loader.BootLoader.loadLibrary("jimage");
return null;
}
});
The problem here is that this file is also compiled as part of the jrtfs.jar, where `BootLoader` is not available, so I also had to do
diff --git a/make/Main.gmk b/make/Main.gmk
index 9fc5490a1ef..606dd215e72 100644
--- a/make/Main.gmk
+++ b/make/Main.gmk
@@ -1000,7 +1000,7 @@ else
# When creating the BUILDJDK, we don't need to add hashes to java.base, thus
# we don't need to depend on all other jmods
ifneq ($(CREATING_BUILDJDK), true)
- java.base-jmod: jrtfs-jar $(addsuffix -jmod, $(filter-out java.base, $(sort \
+ java.base-jmod: $(addsuffix -jmod, $(filter-out java.base, $(sort \
$(foreach m, $(filter-out $(call FindAllUpgradeableModules), $(JMOD_MODULES)), \
$m $(call FindTransitiveDepsForModules, $m) \
))))
to be able to compile this.
But this seems to be the wrong approach. `System.loadLibrary("jimage")` should be able to figure out that an internal, statically-linked, library is being requested. Or at least, I guess that is a reasonable approach? I searched for `System.loadLibrary` and we're doing that a lot to connect to our internal native libraries. (One alternative approach would have been that the JDK should have a separate way to load its own internal libraries, that is not exposed to user code. I was honestly a bit surprised to find out that this is not the case.)
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20837#issuecomment-2452258062
More information about the core-libs-dev
mailing list