From e5f421bad98ed00a5c8695f670cc70c154d1483b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xerxes=20R=C3=A5nby?= Date: Tue, 22 Dec 2015 13:33:44 +0100 Subject: [PATCH 1/2] OpenJDK 8: Add JDK8u JDK-8061651 API. IcedTea PR2775. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement minimal JVM functionality to tell JDK8u that the JDK-8061651 API is unsupported by JamVM JVM_GetResourceLookupCacheURLs JVM_GetResourceLookupCache JVM_KnownToNotExist Signed-off-by: Xerxes Rånby --- src/classlib/openjdk/jvm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/classlib/openjdk/jvm.c b/src/classlib/openjdk/jvm.c index 223f668..cd31b4d 100644 --- a/src/classlib/openjdk/jvm.c +++ b/src/classlib/openjdk/jvm.c @@ -669,6 +669,35 @@ void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers) { } +/* JVM_GetResourceLookupCacheURLs + is part of the + JDK-8061651 JDK8u API +*/ + +jobjectArray JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader) { + return NULL; // tell OpenJDK 8 that the lookup cache API is unavailable +} + +/* JVM_GetResourceLookupCache + is unused however it is part of the + JDK-8061651 JDK8u API +*/ + +jintArray JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name) { + UNIMPLEMENTED("JVM_GetResourceLookupCache"); + return 0; +} + +/* JVM_KnownToNotExist + is unused however it is part of the + JDK-8061651 JDK8u API +*/ + +jboolean JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname) { + UNIMPLEMENTED("JVM_KnownToNotExist"); + return 0; +} + /* JVM_GetProtectionDomain */ jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls) { From cbd141e7e7d473d60f9b5959b6880fb6301b64da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 21:27:56 +0100 Subject: [PATCH 2/2] Fix Class.getClassLoader() always returning null for OpenJDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JDK-6642881 [1] added a classLoader field to java.lang.Class and changed getClassLoader0() from a native method to a direct field accessor [2]. This first landed in OpenJDK 9, but was backported to OpenJDK 8 and OpenJDK 7. JamVM was not populating this field when defining classes, so Class.getClassLoader() would always return null. Fix by caching the offset of the classLoader field during linking and setting it when defining a class. The logic is in OpenJDK classlib hooks (classlibCacheClassFields / classlibSetClassLoader), with no-op macros for GNU Classpath. [1]: https://bugs.openjdk.org/browse/JDK-6642881 [2]: https://github.com/openjdk/jdk/commit/aa12c8fb Signed-off-by: Guillermo Rodríguez --- src/class.c | 5 +++++ src/classlib/gnuclasspath/classlib.h | 3 +++ src/classlib/openjdk/class.c | 17 +++++++++++++++++ src/classlib/openjdk/classlib.h | 2 ++ src/symbol.h | 1 + 5 files changed, 28 insertions(+) diff --git a/src/class.c b/src/class.c index af81530..26d078d 100644 --- a/src/class.c +++ b/src/class.c @@ -379,6 +379,7 @@ Class *parseClass(char *classname, char *data, int offset, int len, } classblock->class_loader = class_loader; + classlibSetClassLoader(class, class_loader); READ_U2(intf_count = classblock->interfaces_count, ptr, len); interfaces = classblock->interfaces = @@ -813,6 +814,7 @@ Class *createArrayClass(char *classname, Object *class_loader) { /* The array's classloader is the loader of the element class */ classblock->class_loader = elem_cb->class_loader; + classlibSetClassLoader(class, elem_cb->class_loader); /* The array's visibility (i.e. public, etc.) is that of the element */ classblock->access_flags = (elem_cb->access_flags & ~ACC_INTERFACE) | @@ -1474,6 +1476,9 @@ void linkClass(Class *class) { cb->flags |= CLASS_LOADER; } + if(cb->flags & CLASS_CLASS) + classlibCacheClassFields(class); + cb->state = CLASS_LINKED; unlock: diff --git a/src/classlib/gnuclasspath/classlib.h b/src/classlib/gnuclasspath/classlib.h index dacc273..1ecf9f9 100644 --- a/src/classlib/gnuclasspath/classlib.h +++ b/src/classlib/gnuclasspath/classlib.h @@ -76,6 +76,9 @@ extern void classlibNewLibraryUnloader(Object *class_loader, void *entry); #define classlibSkipReflectionLoader(loader) \ loader +#define classlibCacheClassFields(class) {} +#define classlibSetClassLoader(class, loader) {} + #define classlibInjectedFieldsCount(classname) 0 #define classlibFillInInjectedFields(classname, field) {} diff --git a/src/classlib/openjdk/class.c b/src/classlib/openjdk/class.c index 3206ed0..148445c 100644 --- a/src/classlib/openjdk/class.c +++ b/src/classlib/openjdk/class.c @@ -26,6 +26,11 @@ #include "excep.h" #include "symbol.h" +/* Cached offset of classLoader field in java.lang.Class. + Since JDK-6642881, Class.getClassLoader0() reads this + field directly rather than calling a native method. */ +static int cls_classLoader_offset = -1; + /* Cached offset of classes field in java.lang.ClassLoader objects */ int ldr_classes_offset; int ldr_parent_offset; @@ -53,6 +58,18 @@ void classlibCacheClassLoaderFields(Class *loader_class) { ldr_parent_offset = parent_fb->u.offset; } +void classlibCacheClassFields(Class *class) { + FieldBlock *cl_fb = findField(class, SYMBOL(classLoader), + SYMBOL(sig_java_lang_ClassLoader)); + if(cl_fb != NULL) + cls_classLoader_offset = cl_fb->u.offset; +} + +void classlibSetClassLoader(Class *class, Object *loader) { + if(loader != NULL && cls_classLoader_offset != -1) + INST_DATA(class, Object*, cls_classLoader_offset) = loader; +} + HashTable *classlibLoaderTable(Object *class_loader) { void *pntr = INST_DATA(class_loader, void*, ldr_classes_offset); diff --git a/src/classlib/openjdk/classlib.h b/src/classlib/openjdk/classlib.h index 23c1b4c..015dfb2 100644 --- a/src/classlib/openjdk/classlib.h +++ b/src/classlib/openjdk/classlib.h @@ -53,6 +53,8 @@ extern void classlibSignalThread(Thread *self); /* NOTHING TO DO */ TRUE extern void classlibCacheClassLoaderFields(Class *loader_class); +extern void classlibCacheClassFields(Class *class); +extern void classlibSetClassLoader(Class *class, Object *loader); extern HashTable *classlibLoaderTable(Object *class_loader); extern HashTable *classlibCreateLoaderTable(Object *class_loader); extern Object *classlibBootPackage(PackageEntry *entry); diff --git a/src/symbol.h b/src/symbol.h index 8864fcb..b910dd5 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -53,6 +53,7 @@ extern char *symbol_values[]; action(initCause, "initCause"), \ action(loadClass, "loadClass"), \ action(returnType, "returnType"), \ + action(classLoader, "classLoader"), \ action(declaringClass, "declaringClass"), \ action(parameterTypes, "parameterTypes"), \ action(printStackTrace, "printStackTrace"), \