diff options
Diffstat (limited to 'libjava/java/lang')
-rw-r--r-- | libjava/java/lang/VMClassLoader.java | 12 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 20 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 36 | ||||
-rw-r--r-- | libjava/java/lang/natVMClassLoader.cc | 25 |
4 files changed, 67 insertions, 26 deletions
diff --git a/libjava/java/lang/VMClassLoader.java b/libjava/java/lang/VMClassLoader.java index c0739ba..dfbfba4 100644 --- a/libjava/java/lang/VMClassLoader.java +++ b/libjava/java/lang/VMClassLoader.java @@ -53,6 +53,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; +import gnu.gcj.runtime.BootClassLoader; /** * java.lang.VMClassLoader is a package-private helper for VMs to implement @@ -82,6 +83,10 @@ final class VMClassLoader static final HashMap definedPackages = new HashMap(); + // This is a helper for handling java.endorsed.dirs. It is null + // until we've initialized the system, at which point it is created. + static BootClassLoader bootLoader; + /** * Helper to define a class using a string of bytes. This assumes that * the security checks have already been performed, if necessary. @@ -153,6 +158,8 @@ final class VMClassLoader */ static URL getResource(String name) { + if (bootLoader != null) + return bootLoader.bootGetResource(name); return null; } @@ -168,6 +175,8 @@ final class VMClassLoader */ static Enumeration getResources(String name) throws IOException { + if (bootLoader != null) + return bootLoader.bootGetResources(name); return EmptyEnumeration.getInstance(); } @@ -287,6 +296,8 @@ final class VMClassLoader static native ClassLoader getSystemClassLoaderInternal(); + static native void initBootLoader(String libdir); + static ClassLoader getSystemClassLoader() { // This method is called as the initialization of systemClassLoader, @@ -310,6 +321,7 @@ final class VMClassLoader + loader, ex); } } + return default_sys; } } diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index f48a6fd..b936947 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -126,16 +126,16 @@ java::lang::Class::getClassLoader (void) s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader"))); } - // The spec requires us to return `null' for primitive classes. In - // other cases we have the option of returning `null' for classes - // loaded with the bootstrap loader. All gcj-compiled classes which - // are linked into the application used to return `null' here, but - // that confuses some poorly-written applications. It is a useful - // and apparently harmless compatibility hack to simply never return - // `null' instead. - if (isPrimitive ()) - return NULL; - return loader ? loader : ClassLoader::systemClassLoader; + // This particular 'return' has been changed a couple of times over + // libgcj's history. This particular approach is a little weird, + // because it means that all classes linked into the application + // will see NULL for their class loader. This may confuse some + // applications that aren't expecting this; the solution is to use a + // different linking model for these applications. In the past we + // returned the system class loader in this case, but that is + // incorrect. Also, back then we didn't have other linkage models + // to fall back on. + return loader; } java::lang::reflect::Constructor * diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index dfb976a..c3b1f7e 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -43,6 +43,7 @@ details. */ #include <java/io/Serializable.h> #include <java/lang/Cloneable.h> #include <java/util/HashMap.h> +#include <gnu/gcj/runtime/BootClassLoader.h> // Size of local hash table. #define HASH_LEN 1013 @@ -106,7 +107,7 @@ void _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) { if (! loader) - loader = java::lang::ClassLoader::systemClassLoader; + loader = java::lang::VMClassLoader::bootLoader; loader->loadedClasses->put(klass->name->toString(), klass); } @@ -116,7 +117,7 @@ void _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) { if (! loader) - loader = java::lang::ClassLoader::systemClassLoader; + loader = java::lang::VMClassLoader::bootLoader; loader->loadedClasses->remove(klass->name->toString()); } @@ -211,13 +212,14 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) // See if the class was already loaded by this loader. This handles // initiating loader checks, as we register classes with their // initiating loaders. - java::lang::ClassLoader *sys = java::lang::ClassLoader::systemClassLoader; + + java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader; java::lang::ClassLoader *real = loader; if (! real) - real = sys; + real = boot; jstring sname = name->toString(); // We might still be bootstrapping the VM, in which case there - // won't be a system class loader yet. + // won't be a bootstrap class loader yet. jclass klass = real ? real->findLoadedClass (sname) : NULL; if (! klass) @@ -230,16 +232,16 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) // If "loader" delegated the loadClass operation to another // loader, explicitly register that it is also an initiating // loader of the given class. - java::lang::ClassLoader *delegate = (loader == sys + java::lang::ClassLoader *delegate = (loader == boot ? NULL : loader); if (klass && klass->getClassLoaderInternal () != delegate) _Jv_RegisterInitiatingLoader (klass, loader); } - else if (sys) + else if (boot) { // Load using the bootstrap loader jvmspec 5.3.1. - klass = sys->loadClass (sname, false); + klass = java::lang::VMClassLoader::loadClass (sname, false); // Register that we're an initiating loader. if (klass) @@ -250,9 +252,21 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) // Not even a bootstrap loader, try the built-in cache. klass = _Jv_FindClassInCache (name); - if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE) - abort (); - bootstrap_class_list[bootstrap_index++] = klass; + bool found = false; + for (int i = 0; i < bootstrap_index; ++i) + { + if (bootstrap_class_list[i] == klass) + { + found = true; + break; + } + } + if (! found) + { + if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE) + abort (); + bootstrap_class_list[bootstrap_index++] = klass; + } } } else diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc index 9a539d7..c59e1d6 100644 --- a/libjava/java/lang/natVMClassLoader.cc +++ b/libjava/java/lang/natVMClassLoader.cc @@ -25,6 +25,7 @@ details. */ #include <java/lang/VMCompiler.h> #include <gnu/gcj/runtime/VMClassLoader.h> #include <gnu/gcj/runtime/SystemClassLoader.h> +#include <gnu/gcj/runtime/BootClassLoader.h> #include <java/lang/ClassLoader.h> #include <java/lang/Class.h> #include <java/lang/Throwable.h> @@ -66,9 +67,9 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader, // until we're done loading. JvSynchronize sync (klass); - // Record the defining loader. For the system class loader, we - // record NULL. - if (loader != java::lang::ClassLoader::systemClassLoader) + // Record the defining loader. For the bootstrap class loader, + // we record NULL. + if (loader != bootLoader) klass->loader = loader; if (name != 0) @@ -122,11 +123,25 @@ java::lang::VMClassLoader::getPrimitiveClass (jchar type) return _Jv_FindClassFromSignature (sig, NULL); } +void +java::lang::VMClassLoader::initBootLoader(jstring libdir) +{ + bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir); +} + jclass java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve) { - _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name); - jclass klass = _Jv_FindClassInCache (utf); + // We try the boot loader first, so that the endorsed directory + // overrides compiled-in classes. + jclass klass = NULL; + if (bootLoader) + klass = bootLoader->bootLoadClass(name); + if (! klass) + { + _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name); + klass = _Jv_FindClassInCache (utf); + } if (klass) { // We never want to return a class without its supers linked. |