This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: bootclassloader problem (gcc 4.0 regression)
On 4/13/05, Mark Wielaard <mark@klomp.org> wrote:
> Hi,
>
> On Wed, 2005-04-13 at 00:40 -0700, Per Bothner wrote:
> > The StackTrace in Class::forName (jstring className) find the correct
> > klass, and does klass->getClassLoaderInternal(). That yields null,
> > which is then passed to _Jv_FindClass. The latter interprets null as
> > the bootLoader, which as far as I can tell does *not* search the
> > CLASS_PATH - not even the default "file:./". I'm not sure though -
> > this seems rather confusing.
>
> OK this makes sense. You get this from gnu.expr.ModuleInfo which is
> compiled into the application. Classes compiled into the application are
> assumed to be loaded through the bootstrap class loader (null). The
> bootstrap classloader should indeed not use the java.class.path
> (CLASSPATH, etc). Only the system class loader should do this.
> gcj 3.x had a bug that the bootstrap class loader also searched the
> java.class.path for byte code class files. This is now never done
> anymore except for classes in the java.endorsed.dirs.
>
> What is confusing is the fact that Class.getClassLoader() has a special
> hack for compiled in classes:
>
> [...] 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.
> return loader ? loader : ClassLoader::systemClassLoader;
>
> What this means is that for compiled in classes of a binary
> Class.getClassLoader() would return the system class loader, but
> internally (in we use Class.getInternalClassLoader() which would return
> null (indicating the bootstrap class loader). Which explains why now
> loading with Class.forName("bla") fails but Class.forName("bla", true,
> getClass().getClassLoader()) succeeds for you.
>
> Ugly. I don't have a real solution for this yet.
> Except to rewrite the kawa ModuleInfo.getInstance() to always explicitly
> use ClassLoader.getSystemClassLoader().
>
> One could say that classes compiled into an application should always
> been seen as being loaded through the system class loader (that makes
> sense to me at least). But I don't know if that can be done easily or
> transparently.
Yes, I'd consider this a bug. An extension mechanism that could
otherwise be very popular with GCJ is to compile an application's core
classes to native code, and allow extensions to be loaded from
jar/class files by adding them to the classpath and setting a property
somewhere, using a simple Class.forName() internally. I know it is
possible to do this using a custom class loader, but many apps just do
it the simple way, and rightly so.
Consider the typical case of a JDBC driver, which is registered and
loaded by adding it to the classpath and doing a Class.forName() in
the app code. Isn't it a pretty massive constraint if this doesn't
work between a native app and a jared/class-compiled driver?
Hannes
>
> Cheers,
>
> Mark
>
>
>