This happens if a class and its superclass are loaded by the boot classloader. If one if them is in the precompiled database and one isn't, we fail this check:
if ( sub->loader != super->loader || !_Jv_ClassNameSamePackage (sub->name, super->name)) { throw_incompatible_class_change_error (sub->getName ()); }
We fail this check becasue of this line in natVMClassLoader.cc
// Record the defining loader. For the bootstrap class loader, // we record NULL. if (loader != bootLoader) klass->loader = loader;
So, at the point of this test:
sub->loader != super->loader
sub->loader == bootLoader, and super->loader == NULL.
All this happens because when a class is loaded by natSharedLibLoader, we do this:
void _Jv_sharedlib_register_hook (jclass cls) { cls->protectionDomain = curHelper->domain; cls->loader = curLoader; if (! cls->engine) cls->engine = &_Jv_soleCompiledEngine; curHelper->registerClass(cls->getName(), cls); }
note that we always set the loader; we don't check for it being the bootLoader.
There are several ways to fix this. We need it for FC6.
Andrew.
2006-07-25 Andrew Haley aph@redhat.com
* gnu/gcj/runtime/natSharedLibLoader.cc (init): Don't set curLoader to VMClassLoader::bootLoader.
--- natSharedLibLoader.cc~ 2006-07-25 16:47:05.000000000 +0100 +++ natSharedLibLoader.cc 2006-07-25 18:11:25.000000000 +0100 @@ -20,6 +20,8 @@ #include <java/lang/UnsupportedOperationException.h> #include <java/lang/UnknownError.h>
+#include <java/lang/VMClassLoader.h> + // If we're using the Boehm GC, then we need this include to override dlopen. #ifdef HAVE_BOEHM_GC // Set GC_DEBUG before including gc.h! @@ -87,7 +89,8 @@ flags = RTLD_GLOBAL | RTLD_LAZY; JvSynchronize dummy1(&java::lang::Class::class$); SharedLibDummy dummy2; - curLoader = loader; + curLoader = ((void*)loader == java::lang::VMClassLoader::bootLoader + ? NULL : loader); curHelper = this; _Jv_RegisterClassHook = _Jv_sharedlib_register_hook; _Jv_RegisterCoreHook = core_hook;