jserv/jamvm

Unable to initialize JamVM on macOS

Opened this issue · 1 comments

jserv commented

Using OpenJDK 8 from Eclipse Temurin, JRE failed to initialize JamVM:

$ bin/java -XXaltjvm=jamvm -version
Exception occurred while VM initialising.
java/lang/NoClassDefFoundError: java/lang/ClassLoader

Known reasons:

  1. Different JRE layout: JRE for GNU/Linux has explicit architecture directory, such as jre/lib/amd64, but JRE for macOS has dynamic libraries in directory jre/lib.
  2. Different java_home information: It indicates to JRE directory on GNU/Linux, but Contents/Home is specified on macOS.

Test environment

  • macOS Catalina 10.15.7, x86-64
  • OpenJDK 8.0.352
$ bin/java -version
openjdk version "1.8.0_352"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_352-b08)
OpenJDK 64-Bit Server VM (Temurin)(build 25.352-b08, mixed mode)
jserv commented

I use Azul JDK instead. In particular, Zulu JRE8.0-352 based on OpenJDK 8. Apply the following patch:

diff --git a/src/classlib/openjdk/class.c b/src/classlib/openjdk/class.c
index 3206ed0..e2bb744 100644
--- a/src/classlib/openjdk/class.c
+++ b/src/classlib/openjdk/class.c
@@ -136,10 +136,10 @@ char *classlibDefaultBootClassPath() {
     if(i == 0)
         return "";
 
-    pntr = path = sysMalloc(len + i * (strlen(java_home) + 2));
+    pntr = path = sysMalloc(len + i * (strlen(java_home) + 2 + 5));
 
     for(j = 0; j < i - 1; j++)
-        pntr += sprintf(pntr, "%s/%s:", java_home, entries[j]);
+        pntr += sprintf(pntr, "%s/Home/%s:", java_home, entries[j]);
 
     sprintf(pntr, "%s/%s", java_home, entries[j]);
     
diff --git a/src/classlib/openjdk/dll.c b/src/classlib/openjdk/dll.c
index 1d9cc9c..77498f6 100644
--- a/src/classlib/openjdk/dll.c
+++ b/src/classlib/openjdk/dll.c
@@ -43,9 +43,9 @@ int classlibInitialiseDll() {
 
 char *classlibDefaultBootDllPath() {
     char *java_home = getJavaHome();
-    char *dll_path = sysMalloc(strlen(java_home) + sizeof("/lib/"OS_ARCH));
+    char *dll_path = sysMalloc(strlen(java_home) + sizeof("/Home/lib"));
 
-    return strcat(strcpy(dll_path, java_home), "/lib/"OS_ARCH);
+    return strcat(strcpy(dll_path, java_home), "/Home/lib");
 }
 
 void *classlibLookupLoadedDlls(char *name, Object *loader) {

And make dyld happy:

export DYLD_LIBRARY_PATH=/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/:/private/tmp/zulu8.66.0.15-ca-jre8.0.352-macosx_x64/zulu-8.jre/Contents/Home/lib/:/System/Library/Frameworks/ImageIO.framework/Resources/:/usr/local/lib/:/usr/lib/:/opt/homebrew/lib/:/private/tmp/zulu8.66.0.15-ca-jre8.0.352-macosx_x64/zulu-8.jre/Contents/Home/lib/jamvm/

Then Zulu JDK can display version information on macOS.

$ bin/java -XXaltjvm=jamvm -version
openjdk version "1.8.0_352"
OpenJDK Runtime Environment (Zulu 8.66.0.15-CA-macosx) (build 1.8.0_352-b08)
JamVM (Zulu 8.66.0.15-CA-macosx) (build 2.0.1-devel, inline-threaded interpreter)