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(a)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;