Description of problem: When compiling a javafx bundle for distribution, the fedora openjdk is copied in the bundle. Compared to some other distributions of the openjdk (e.g. oracle), the linked C symbols in some .so require high version of the glibc, which makes the app crash on other distributions. For example, building on fedora 29 crashes on ubuntu 18 because the required glibc version is 2.28 and ubuntu has 2.27. #oracle jdk nm jdk1.8.0_202/jre/lib/amd64/libnio.so | grep -o @@GLIBC.*[0-9]* | sort | uniq -c 90 @@GLIBC_2.2.5 2 @@GLIBC_2.3 3 @@GLIBC_2.3.2 4 @@GLIBC_2.4 # fedora 28 openjdk $ nm /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.fc29.x86_64/jre/lib/amd64/libnio.so | grep -o @@GLIBC.*[0-9]* | sort | uniq -c 90 @@GLIBC_2.2.5 1 @@GLIBC_2.28 1 @@GLIBC_2.3 3 @@GLIBC_2.3.2 5 @@GLIBC_2.4 1 @@GLIBC_2.7 $ ./hello-world java.lang.UnsatisfiedLinkError: /tmp/gse-fedo/runtime/lib/amd64/libnio.so: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by /tmp/gse-fedo/runtime/lib/amd64/libnio.so) at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1845) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at sun.nio.fs.UnixNativeDispatcher$1.run(UnixNativeDispatcher.java:573) at sun.nio.fs.UnixNativeDispatcher$1.run(UnixNativeDispatcher.java:571) at java.security.AccessController.doPrivileged(Native Method) at sun.nio.fs.UnixNativeDispatcher.<clinit>(UnixNativeDispatcher.java:571) at sun.nio.fs.UnixFileSystem.<init>(UnixFileSystem.java:67) at sun.nio.fs.LinuxFileSystem.<init>(LinuxFileSystem.java:39) at sun.nio.fs.LinuxFileSystemProvider.newFileSystem(LinuxFileSystemProvider.java:46) at sun.nio.fs.LinuxFileSystemProvider.newFileSystem(LinuxFileSystemProvider.java:39) at sun.nio.fs.UnixFileSystemProvider.<init>(UnixFileSystemProvider.java:56) at sun.nio.fs.LinuxFileSystemProvider.<init>(LinuxFileSystemProvider.java:41) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at sun.nio.fs.DefaultFileSystemProvider.createProvider(DefaultFileSystemProvider.java:48) at sun.nio.fs.DefaultFileSystemProvider.create(DefaultFileSystemProvider.java:63) at java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:108) at java.nio.file.FileSystems$DefaultFileSystemHolder.access$000(FileSystems.java:89) at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:98) at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:96) at java.security.AccessController.doPrivileged(Native Method) at java.nio.file.FileSystems$DefaultFileSystemHolder.defaultFileSystem(FileSystems.java:96) at java.nio.file.FileSystems$DefaultFileSystemHolder.<clinit>(FileSystems.java:90) at java.nio.file.FileSystems.getDefault(FileSystems.java:176) [...] Version-Release number of selected component (if applicable): How reproducible: always Steps to Reproduce: 1. build a javafx bundle on fedora 29 2. run it on ubuntu 18.04 3. Actual results: doesn't work Expected results: should work Additional info:
libnio.so is supplied by the openjdk package and not the openjdk package, reassigning
Jon, I'm not sure what "build a javafx bundle" means exactly and how it works. But from the stacktrace it appears it bundles JDK libs and/or the JDK runtime. If that's the case, then this behaviour is expected. Fedora OpenJDK rpm builds are distribution integrated and are as such not portable to non-Fedora distributions. From the sounds of it, you want to do bundling of the JDK. For this to have a chance of working, you'd need to start from a portable JDK build to begin with. Distribution builds of Fedora are not that. Example of libsunec.so on Fedora (they directly link to system libraries): $ rpm -ql java-1.8.0-openjdk-headless | grep libsunec /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-6.fc29.x86_64/jre/lib/amd64/libsunec.so $ ldd /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-6.fc29.x86_64/jre/lib/amd64/libsunec.so linux-vdso.so.1 (0x00007fffda3ff000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fa60064e000) libssl3.so => /lib64/libssl3.so (0x00007fa6005f3000) libsmime3.so => /lib64/libsmime3.so (0x00007fa6005c8000) libnss3.so => /lib64/libnss3.so (0x00007fa600497000) libnssutil3.so => /lib64/libnssutil3.so (0x00007fa600464000) libplds4.so => /lib64/libplds4.so (0x00007fa60045f000) libplc4.so => /lib64/libplc4.so (0x00007fa600456000) libnspr4.so => /lib64/libnspr4.so (0x00007fa600414000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa6003f2000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fa6003ec000) libm.so.6 => /lib64/libm.so.6 (0x00007fa600268000) libc.so.6 => /lib64/libc.so.6 (0x00007fa6000a2000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fa600085000) /lib64/ld-linux-x86-64.so.2 (0x00007fa600827000) librt.so.1 => /lib64/librt.so.1 (0x00007fa60007b000) $ rpm -qf /lib64/libnss3.so nss-3.43.0-1.fc29.x86_64 Contrast this to a portable build [1]: $ ./bin/java -version openjdk version "1.8.0_212" OpenJDK Runtime Environment (build 1.8.0_212-b03) OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode) $ find | grep sunec.so ./jre/lib/amd64/libsunec.so $ ldd ./jre/lib/amd64/libsunec.so linux-vdso.so.1 (0x00007ffc2d03b000) libc.so.6 => /lib64/libc.so.6 (0x00007f70d2dc8000) /lib64/ld-linux-x86-64.so.2 (0x00007f70d320a000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f70d2dad000) Of course there remain certain dependencies still, like in your example, glibc. The approach taken to make them as portable as possible is to build on older systems, like CentOS 6, so that minimal glibc requirement will likely be satisfied. With that said, there are still systems on which those "portable" builds won't run. For example on CentOS 5, even the Oracle JDK build would likely not run. You've got a couple of options: 1.) Use the Fedora stack, but package it as a container image. Run the container image on the host system you need. 2.) Get a portable OpenJDK build, use that JDK as base for your javafx bundle. I'm not sure whether any of them have OpenJFX integrated, though. So you might have to jump through some hoops. E.g. [1] or their vendor'ed AdoptOpenJDK builds Currently there are no plans to ship a portable OpenJDK as part of the Fedora distribution via RPMs. So from a distribution point of view, there is little we can do. [1] https://adoptopenjdk.net/upstream.html
Closing this as per comment 2. OpenJDK rpm builds in fedora build with the distro glibc version (there is only one per Fedora version), hence the error is expected. Feel free to reopen if I got something wrong.
Hi, Thank you for taking the time to answer. I understand your point. I'm curious though, are languages like C or go when linking statically considered the same ? IE can the fedora shipped gcc or golang be officially used to build a static binary that will run on another distro ? If so, why support it on C/go and not java ? Is it because upstream go is designed for it, whereas upstream java is not considered designed for it ? Cheers, Jon PS: > I'm not sure what "build a javafx bundle" means exactly and how it works. But from the stacktrace it appears it bundles JDK libs and/or the JDK runtime. Also, for the record, here's an example build of a bundle from the command line, which should point you to the relevant documentation. Your guess was pretty accurate: # using jdk8 $ cat src/HelloWorld.java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } $ javac -d classes/ src/HelloWorld.java $ javapackager -createjar -appclass HelloWorld -srcdir classes/ -outdir out -outfile outjar -v $ javapackager -deploy -native image -srcfiles out/outjar.jar -appclass HelloWorld -outdir out -outfile test No base JDK. Package will use system JRE. No base JDK. Package will use system JRE. Creating app bundle: out/bundles/HelloWorld $ file out/bundles/HelloWorld/HelloWorld out/bundles/HelloWorld/HelloWorld: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=611374360cf037f66687a6b91d3b629e9f660361, not stripped $ /tmp/foo/out/bundles/HelloWorld/HelloWorld Hello World!
Jon, what this appears to be doing is simply bundling some dynamic so's and not generating a statically linked executable, so I don't think it's analogous to C/Go at all.