From daadd9cbfc39b7cbef2f68255d1fc81ca5124ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 19:17:22 +0100 Subject: [PATCH 1/3] Fix VM init failure due to wrong java.home on OpenJDK/Darwin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When built for OpenJDK on Darwin, VM fails during init: Exception occurred while VM initialising. java/lang/NoClassDefFoundError: java/lang/ClassLoader This is due to an invalid value being derived for java.home: Both classlibDefaultJavaHome() and classlibDefaultBootDllPath() expect the java.home directory to be 4 path components up from the location of libjvm. This is correct on most platforms where libjvm lives at /lib///libjvm.so [1], but not on Darwin, where there is no architecture subdirectory and libjvm lives at /lib//libjvm.dylib [2]. Fix by adjusting the lookup code in classlibDefaultJavaHome() and classlibDefaultBootDllPath() on Darwin. [1]: https://github.com/openjdk/jdk8u/blob/jdk8u482-ga/jdk/src/solaris/bin/java_md_solinux.c#L792 [2]: https://github.com/openjdk/jdk8u/blob/jdk8u482-ga/jdk/src/macosx/bin/java_md_macosx.c#L591 Signed-off-by: Guillermo Rodríguez --- src/classlib/openjdk/dll.c | 9 +++++++++ src/classlib/openjdk/properties.c | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/classlib/openjdk/dll.c b/src/classlib/openjdk/dll.c index 1d9cc9c..5d42dff 100644 --- a/src/classlib/openjdk/dll.c +++ b/src/classlib/openjdk/dll.c @@ -43,9 +43,18 @@ int classlibInitialiseDll() { char *classlibDefaultBootDllPath() { char *java_home = getJavaHome(); + + /* On most platforms, native libraries are in lib//. + On Darwin, they are directly in lib/. */ +#ifdef __APPLE__ + char *dll_path = sysMalloc(strlen(java_home) + sizeof("/lib")); + + return strcat(strcpy(dll_path, java_home), "/lib"); +#else char *dll_path = sysMalloc(strlen(java_home) + sizeof("/lib/"OS_ARCH)); return strcat(strcpy(dll_path, java_home), "/lib/"OS_ARCH); +#endif } void *classlibLookupLoadedDlls(char *name, Object *loader) { diff --git a/src/classlib/openjdk/properties.c b/src/classlib/openjdk/properties.c index 2391e61..dc7a1f8 100644 --- a/src/classlib/openjdk/properties.c +++ b/src/classlib/openjdk/properties.c @@ -27,10 +27,19 @@ char *classlibDefaultJavaHome() { int count = 0; char *home; - while(pntr > path && count < 4) + /* Derive java.home from the location of libjvm. + Default (most platforms): /lib///libjvm.so + Darwin (no arch subdir): /lib//libjvm.dylib */ +#ifdef __APPLE__ + int n_sep = 3; +#else + int n_sep = 4; +#endif + + while(pntr > path && count < n_sep) count += *--pntr == '/'; - if(count != 4) { + if(count != n_sep) { printf("Error: JVM path malformed. Aborting VM.\n"); exitVM(1); } From e2b121f69d37568626b4722c636fd86d7755e875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 19:38:18 +0100 Subject: [PATCH 2/3] Fix VM init failure loading native libraries on OpenJDK/Darwin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When built for OpenJDK on Darwin, VM fails during init when loading native libraries: Error initialising natives: couldn't open libjava.so Error initialising VM (initialiseNatives) This happens because on Darwin, OpenJDK's native libraries (such as libjava.dylib) depend on @rpath/libjvm.dylib. At runtime, dyld resolves this by matching against the install name of the library (which is already loaded). However, by default our libjvm.dylib is built with install name /lib/libjvm.dylib, so dyld can't resolve it, and loading libjava.dylib fails. Fix by setting the install name for libjvm to @rpath/libjvm.dylib when building for OpenJDK on Darwin. Signed-off-by: Guillermo Rodríguez --- configure.ac | 8 ++++++++ src/Makefile.am | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3c73795..da96b82 100644 --- a/configure.ac +++ b/configure.ac @@ -378,6 +378,14 @@ fi AC_SUBST(classlib) +dnl On Darwin, the OpenJDK class library's native libraries (e.g. libjava) +dnl reference libjvm via @rpath/libjvm.dylib. Set our install name to match +dnl so that dyld resolves the dependency. +if test "$classlib" = openjdk -a "$host_os" = darwin; then + LIBJVM_EXTRA_LDFLAGS="-Wl,-install_name,@rpath/libjvm.dylib" +fi +AC_SUBST(LIBJVM_EXTRA_LDFLAGS) + case "$with_java_runtime_library" in gnuclasspath | openjdk6 ) AC_DEFINE([SHARED_CHAR_BUFFERS],1, diff --git a/src/Makefile.am b/src/Makefile.am index 1cf2e87..d62ddf2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ libjvm_la_SOURCES = jamvm_LDADD = libcore.la libjvm_la_LIBADD = libcore.la -libjvm_la_LDFLAGS = -avoid-version +libjvm_la_LDFLAGS = -avoid-version @LIBJVM_EXTRA_LDFLAGS@ libcore_la_LIBADD = interp/libinterp.la os/@os@/@arch@/libnative.la \ os/@os@/libos.la classlib/@classlib@/libclasslib.la From b59cd568a4d731eeb54dc1e4053da3d1abe10abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 18:59:19 +0100 Subject: [PATCH 3/3] Fix os.name for OpenJDK/Darwin (macOS) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When built for OpenJDK on Darwin, trying to run a simple Hello World application on macOS fails: java.lang.AssertionError: Platform not recognized at sun.nio.fs.DefaultFileSystemProvider.create(...) This is because JamVM sets os.name from uname(), which returns "Darwin". However, the expected value for macOS is "Mac OS X" (see [1], [2]). This breaks any code that relies on os.name to detect macOS, including parts of the OpenJDK class library itself (e.g. DefaultFileSystemProvider). [1]: https://bugs.openjdk.org/browse/JDK-8004646 [2]: https://developer.apple.com/library/archive/technotes/tn2002/tn2110.html Signed-off-by: Guillermo Rodríguez --- src/properties.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/properties.c b/src/properties.c index b453d7b..a7b11fc 100644 --- a/src/properties.c +++ b/src/properties.c @@ -25,6 +25,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #include "jam.h" #include "symbol.h" #include "hash.h" @@ -161,7 +165,11 @@ void setOSProperties(Object *properties) { uname(&info); setProperty(properties, "os.arch", OS_ARCH); +#if defined(__APPLE__) && !TARGET_OS_IPHONE + setProperty(properties, "os.name", "Mac OS X"); +#else setProperty(properties, "os.name", info.sysname); +#endif setProperty(properties, "os.version", info.release); }