Re: Hermetic Java and static link
CC'ing leyden-dev@openjdk.org Hi Ioi, For the current state of JDK static linking support, the https://github.com/openjdk/leyden/tree/hermetic-java-runtime is about the same as the JDK mainline. Most of the JDK libraries and libjvm are statically linked with the launcher. Please see additional comments below. On Tue, Oct 14, 2025 at 10:04 AM <ioi.lam@oracle.com> wrote:
Hi Jiangli,
I tried building with https://github.com/openjdk/leyden/tree/hermetic-java-runtime to see if I can get a completely statically linked JVM, but the JVM is still dynamically linked to a few shared libraries.
Could you please elaborate on the specific libraries that you are looking into static linking as well? Such as libm, libasound, X11, , etc? What are the specific benefits for statically linking with those? Do you have some context or details on what you are looking for?
Is it possible to do a static link (with "gcc-static ...")?
If I understand the question correctly, -static-libgcc is the default when building JDK on Linux. See https://github.com/openjdk/jdk/blob/3d95c83b14cf9a6f683776053e57c07b1847cc17.... It's the case with linking the libjvm.so as well. E.g.: g++ ... -static-libgcc -shared ... -Wl,-soname=libjvm.so -o support/modules_libs/java.base/server/libjvm.so ... -lm -ldl -lpthread -lrt -static-libstdc++ Thanks, Jiangli
Thanks
- Ioi
$ bash configure $ cd build/linux-x64 $ make static-jdk-bundles $ ls -l build/linux-x64/images/static-jdk/bin/java -rwxr-xr-x. 1 opc opc 34915696 Oct 14 08:55 build/linux-x64/images/static-jdk/bin/java $ ldd images/static-jdk/bin/java linux-vdso.so.1 (0x000075aad82ca000) libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x000075aad64c3000) libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x000075aad829e000) libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x000075aad828b000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x000075aad827f000) libXtst.so.6 => /lib/x86_64-linux-gnu/libXtst.so.6 (0x000075aad8277000) libasound.so.2 => /lib/x86_64-linux-gnu/libasound.so.2 (0x000075aad63b9000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000075aad8270000) libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x000075aad62ed000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000075aad826b000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x000075aad8266000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x000075aad824a000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000075aad6204000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000075aad5e00000) /lib64/ld-linux-x86-64.so.2 (0x000075aad82cc000) libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x000075aad61db000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x000075aad8234000) libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x000075aad61a3000) libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x000075aad6195000) libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x000075aad822c000) libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x000075aad618d000) libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x000075aad616a000) libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x000075aad6154000) libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x000075aad6145000)
Hi Jiangli, We were trying to run the JVM on a "scratch" container image ( https://hub.docker.com/_/scratch ) but were running into problems with missing shared libraries. At first we tried to build the JVM into a static executable, but that turns out to be more complicated that we thought. We ended up simply copying the shared libraries from the build host into the docker image and that seemed to work for our use case.
If I understand the question correctly, -static-libgcc is the default when building JDK on Linux.
-static-libgcc affects only libgcc.a. To link all the other libraries (such as libc) statically, "g++ -static" need to be used. Thanks - Ioi
CC'ingleyden-dev at openjdk.org <https://mail.openjdk.org/mailman/listinfo/leyden-dev>
Hi Ioi,
For the current state of JDK static linking support, the https://github.com/openjdk/leyden/tree/hermetic-java-runtime is about the same as the JDK mainline. Most of the JDK libraries and libjvm are statically linked with the launcher. Please see additional comments below.
On Tue, Oct 14, 2025 at 10:04 AM <ioi.lam at oracle.com <https://mail.openjdk.org/mailman/listinfo/leyden-dev>> wrote:
//>/Hi Jiangli, />//>/I tried building with />/https://github.com/openjdk/leyden/tree/hermetic-java-runtime to see if I />/can get a completely statically linked JVM, but the JVM is still />/dynamically linked to a few shared libraries. / Could you please elaborate on the specific libraries that you are looking into static linking as well? Such as libm, libasound, X11, , etc? What are the specific benefits for statically linking with those?
Do you have some context or details on what you are looking for?
//>/Is it possible to do a static link (with "gcc-static ...")? / If I understand the question correctly, -static-libgcc is the default when building JDK on Linux. See https://github.com/openjdk/jdk/blob/3d95c83b14cf9a6f683776053e57c07b1847cc17.... It's the case with linking the libjvm.so as well. E.g.:
g++ ... -static-libgcc -shared ... -Wl,-soname=libjvm.so -o support/modules_libs/java.base/server/libjvm.so ... -lm -ldl -lpthread -lrt -static-libstdc++
Thanks, Jiangli
//>/Thanks />//>/- Ioi />//>/$ bash configure />/$ cd build/linux-x64 />/$ make static-jdk-bundles />/$ ls -l build/linux-x64/images/static-jdk/bin/java />/-rwxr-xr-x. 1 opc opc 34915696 Oct 14 08:55 />/build/linux-x64/images/static-jdk/bin/java />/$ ldd images/static-jdk/bin/java />/linux-vdso.so.1 (0x000075aad82ca000) />/libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x000075aad64c3000) />/libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x000075aad829e000) />/libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x000075aad828b000) />/libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 />/(0x000075aad827f000) />/libXtst.so.6 => /lib/x86_64-linux-gnu/libXtst.so.6 (0x000075aad8277000) />/libasound.so.2 => /lib/x86_64-linux-gnu/libasound.so.2 />/(0x000075aad63b9000) />/libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000075aad8270000) />/libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 />/(0x000075aad62ed000) />/libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 />/(0x000075aad826b000) />/librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x000075aad8266000) />/libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x000075aad824a000) />/libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000075aad6204000) />/libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000075aad5e00000) />//lib64/ld-linux-x86-64.so.2 (0x000075aad82cc000) />/libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x000075aad61db000) />/libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 />/(0x000075aad8234000) />/libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 />/(0x000075aad61a3000) />/libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 />/(0x000075aad6195000) />/libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x000075aad822c000) />/libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 />/(0x000075aad618d000) />/libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 />/(0x000075aad616a000) />/libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x000075aad6154000) />/libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x000075aad6145000) />
Thanks for the context. The scope of hermetic Java involves statically linking the JDK/VM native libraries. The requirements for statically linking with the other dependency libraries can vary for different applications. As part of the hermetic Java work, we have also experimented with statically linking the JDK bundled native dependency libraries, such as zlib, harfbuzz, etc. Statically linking with libc seems to be challenging, based on the information that I know. According to https://stackoverflow.com/questions/2725255/create-statically-linked-binary-..., musl supports static linking well. Thanks, Jiangli On Wed, Oct 15, 2025 at 9:48 AM <ioi.lam@oracle.com> wrote:
Hi Jiangli,
We were trying to run the JVM on a "scratch" container image ( https://hub.docker.com/_/scratch ) but were running into problems with missing shared libraries.
At first we tried to build the JVM into a static executable, but that turns out to be more complicated that we thought.
We ended up simply copying the shared libraries from the build host into the docker image and that seemed to work for our use case.
If I understand the question correctly, -static-libgcc is the default when building JDK on Linux.
-static-libgcc affects only libgcc.a. To link all the other libraries (such as libc) statically, "g++ -static" need to be used.
Thanks
- Ioi
CC'ing leyden-dev at openjdk.org
Hi Ioi,
For the current state of JDK static linking support, the https://github.com/openjdk/leyden/tree/hermetic-java-runtime is about the same as the JDK mainline. Most of the JDK libraries and libjvm are statically linked with the launcher. Please see additional comments below.
On Tue, Oct 14, 2025 at 10:04 AM <ioi.lam at oracle.com> wrote:
Hi Jiangli,
I tried building with https://github.com/openjdk/leyden/tree/hermetic-java-runtime to see if I can get a completely statically linked JVM, but the JVM is still dynamically linked to a few shared libraries.
Could you please elaborate on the specific libraries that you are looking into static linking as well? Such as libm, libasound, X11, , etc? What are the specific benefits for statically linking with those?
Do you have some context or details on what you are looking for?
Is it possible to do a static link (with "gcc-static ...")?
If I understand the question correctly, -static-libgcc is the default when building JDK on Linux. See https://github.com/openjdk/jdk/blob/3d95c83b14cf9a6f683776053e57c07b1847cc17.... It's the case with linking the libjvm.so as well. E.g.:
g++ ... -static-libgcc -shared ... -Wl,-soname=libjvm.so -o support/modules_libs/java.base/server/libjvm.so ... -lm -ldl -lpthread -lrt -static-libstdc++
Thanks, Jiangli
Thanks
- Ioi
$ bash configure $ cd build/linux-x64 $ make static-jdk-bundles $ ls -l build/linux-x64/images/static-jdk/bin/java -rwxr-xr-x. 1 opc opc 34915696 Oct 14 08:55 build/linux-x64/images/static-jdk/bin/java $ ldd images/static-jdk/bin/java linux-vdso.so.1 (0x000075aad82ca000) libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x000075aad64c3000) libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x000075aad829e000) libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x000075aad828b000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x000075aad827f000) libXtst.so.6 => /lib/x86_64-linux-gnu/libXtst.so.6 (0x000075aad8277000) libasound.so.2 => /lib/x86_64-linux-gnu/libasound.so.2 (0x000075aad63b9000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000075aad8270000) libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x000075aad62ed000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000075aad826b000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x000075aad8266000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x000075aad824a000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000075aad6204000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000075aad5e00000) /lib64/ld-linux-x86-64.so.2 (0x000075aad82cc000) libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x000075aad61db000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x000075aad8234000) libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x000075aad61a3000) libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x000075aad6195000) libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x000075aad822c000) libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x000075aad618d000) libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x000075aad616a000) libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x000075aad6154000) libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x000075aad6145000)
On 16/10/2025 03:15, Jiangli Zhou wrote:
Statically linking with libc seems to be challenging
Arguably, statically liking with libc is just plain wrong, not just challenging. libc can (and IMO should) be considered as part of the operating system. If you link statically against libc things like resolver libraries will break. -- Andrew Haley (he/him) Java Platform Lead Engineer https://keybase.io/andrewhaley EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
Hi Jiangli, Thanks for sharing this info. I am wondering if you somehow create a symbol map that is used at link time? We use the same static compilation concept in openjdk/mobile, but simply linking `-ljava -lnio -lnet` etc will not include the native functions (e.g. Java_java_lang_reflect_Array_get) that are part of e.g. libjava.a etc, because they are not referenced. This can be solved by telling the linker to use force_load (linux) but preferably, we don't want to load symbols that are not used in the final image. There used to be a function in the OpenJDK build process that creates a map with relevant symbols per static library, but I'm not sure it is still used? - Johan On Wed, Oct 15, 2025 at 2:21 AM Jiangli Zhou <jianglizhou@google.com> wrote:
CC'ing leyden-dev@openjdk.org
Hi Ioi,
For the current state of JDK static linking support, the https://github.com/openjdk/leyden/tree/hermetic-java-runtime is about the same as the JDK mainline. Most of the JDK libraries and libjvm are statically linked with the launcher. Please see additional comments below.
On Tue, Oct 14, 2025 at 10:04 AM <ioi.lam@oracle.com> wrote:
Hi Jiangli,
I tried building with https://github.com/openjdk/leyden/tree/hermetic-java-runtime to see if I can get a completely statically linked JVM, but the JVM is still dynamically linked to a few shared libraries.
Could you please elaborate on the specific libraries that you are looking into static linking as well? Such as libm, libasound, X11, , etc? What are the specific benefits for statically linking with those?
Do you have some context or details on what you are looking for?
Is it possible to do a static link (with "gcc-static ...")?
If I understand the question correctly, -static-libgcc is the default when building JDK on Linux. See
https://github.com/openjdk/jdk/blob/3d95c83b14cf9a6f683776053e57c07b1847cc17... . It's the case with linking the libjvm.so as well. E.g.:
g++ ... -static-libgcc -shared ... -Wl,-soname=libjvm.so -o support/modules_libs/java.base/server/libjvm.so ... -lm -ldl -lpthread -lrt -static-libstdc++
Thanks, Jiangli
Thanks
- Ioi
$ bash configure $ cd build/linux-x64 $ make static-jdk-bundles $ ls -l build/linux-x64/images/static-jdk/bin/java -rwxr-xr-x. 1 opc opc 34915696 Oct 14 08:55 build/linux-x64/images/static-jdk/bin/java $ ldd images/static-jdk/bin/java linux-vdso.so.1 (0x000075aad82ca000) libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6
(0x000075aad64c3000)
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6
(0x000075aad829e000)
libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x000075aad828b000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x000075aad827f000) libXtst.so.6 => /lib/x86_64-linux-gnu/libXtst.so.6
(0x000075aad8277000)
libasound.so.2 => /lib/x86_64-linux-gnu/libasound.so.2 (0x000075aad63b9000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000075aad8270000) libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x000075aad62ed000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000075aad826b000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x000075aad8266000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x000075aad824a000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000075aad6204000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000075aad5e00000) /lib64/ld-linux-x86-64.so.2 (0x000075aad82cc000) libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1
(0x000075aad61db000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x000075aad8234000) libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x000075aad61a3000) libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x000075aad6195000) libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6
(0x000075aad822c000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x000075aad618d000) libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x000075aad616a000) libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0
(0x000075aad6154000)
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x000075aad6145000)
participants (4)
-
Andrew Haley
-
ioi.lam@oracle.com
-
Jiangli Zhou
-
Johan Vos