bootstrap class loader

38 views
Skip to first unread message

Jochen Theodorou

unread,
Apr 15, 2009, 9:04:06 PM4/15/09
to jvm-la...@googlegroups.com
Hi all,

it seems the spec isn't all too clear in that area. For our compiler we
would need a ClassLoader that does not load class that are given as
classpath.... I guess I am not very clear....

java -cp A.jar foo.Bar

we now need the class loader that is allowed to laod classes from
rt.jar, but does not laod classes from A.jar. It seems the spec says for
1.2 that the bootstrap class loader will not do that, but how to get a
hand on it? Giving null as parent seems to result in the system class
loader, which is the one that loads the classes from A.jar... so it is
the wrong one.

Is there any way to do this?

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

Jochen Theodorou

unread,
Apr 16, 2009, 10:34:10 AM4/16/09
to jvm-la...@googlegroups.com
Jochen Theodorou schrieb:

> Hi all,
>
> it seems the spec isn't all too clear in that area. For our compiler we
> would need a ClassLoader that does not load class that are given as
> classpath.... I guess I am not very clear....
>
> java -cp A.jar foo.Bar
>
> we now need the class loader that is allowed to load classes from
> rt.jar, but does not laod classes from A.jar. It seems the spec says for
> 1.2 that the bootstrap class loader will not do that, but how to get a
> hand on it? Giving null as parent seems to result in the system class
> loader, which is the one that loads the classes from A.jar... so it is
> the wrong one.
>
> Is there any way to do this?

I take the huge amount of responses, that there is no safe way for this.

am I at last right when I say that if the parent of a class loader is
null, that this does not mean that the loader has the bootstrap loader
as parent?

Matt Fowles

unread,
Apr 16, 2009, 10:37:38 AM4/16/09
to jvm-la...@googlegroups.com
Jochen~

In my experience playing games with classloaders like this leads to to breakage.  I have briefly tried what you are asking about (calling getParent() on a classloader) and it has worked, but I have always later come to the conclusion that what I want to do is error prone and I should find a different approach.

Matt

Jochen Theodorou

unread,
Apr 16, 2009, 10:53:35 AM4/16/09
to jvm-la...@googlegroups.com
Matt Fowles schrieb:

> Jochen~
>
> In my experience playing games with classloaders like this leads to to
> breakage. I have briefly tried what you are asking about (calling
> getParent() on a classloader) and it has worked, but I have always later
> come to the conclusion that what I want to do is error prone and I
> should find a different approach.

and what would that be?

bye Jochen

Matt Fowles

unread,
Apr 16, 2009, 11:02:04 AM4/16/09
to jvm-la...@googlegroups.com
Jochen~

In the particular case that I am thinking of, that I should re-write my tests to not depend on the parent classloader.  In a similar (but not identical case), there was a bug the in the custom classloader that I wrote that I was trying to work around and the correct thing was to find and fix the bug.  You may wish to consider something like OSGI which was designed for this sort of versioning of classes.  It might be too heavy weight for your situation though.

This could of course be my bias, as I find classloaders a bit difficult to work with in general.

Matt

Jeroen Frijters

unread,
Apr 16, 2009, 11:08:52 AM4/16/09
to jvm-la...@googlegroups.com
Hi Jochen,

Maybe I'm misunderstanding you, but isn't it as simple as this:

public class test
{
public static void main(String[] args) throws Exception
{
ClassLoader cl = new ClassLoader(null) { };
System.out.println(cl.loadClass("java.lang.Object"));
System.out.println(cl.loadClass("test"));
}
}

The cl ClassLoader will only load bootstrap classes. If you run this the result is:
class java.lang.Object
Exception in thread "main" java.lang.ClassNotFoundException: test
at java.lang.ClassLoader.findClass(ClassLoader.java:359)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at test.main(test.java:7)

Regards,
Jeroen

Jochen Theodorou

unread,
Apr 16, 2009, 2:58:18 PM4/16/09
to jvm-la...@googlegroups.com
Jeroen Frijters schrieb:

> Hi Jochen,
>
> Maybe I'm misunderstanding you, but isn't it as simple as this:
>
> public class test
> {
> public static void main(String[] args) throws Exception
> {
> ClassLoader cl = new ClassLoader(null) { };
> System.out.println(cl.loadClass("java.lang.Object"));
> System.out.println(cl.loadClass("test"));
> }
> }
>
> The cl ClassLoader will only load bootstrap classes. If you run this the result is:
> class java.lang.Object
> Exception in thread "main" java.lang.ClassNotFoundException: test
> at java.lang.ClassLoader.findClass(ClassLoader.java:359)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
> at test.main(test.java:7)

yes, but is that specified?

bye Jochen

James Abley

unread,
Apr 16, 2009, 3:31:33 PM4/16/09
to jvm-la...@googlegroups.com
2009/4/16 Jochen Theodorou <blac...@gmx.org>:

>
> Jeroen Frijters schrieb:
>> Hi Jochen,
>>
>> Maybe I'm misunderstanding you, but isn't it as simple as this:
>>
>> public class test
>> {
>>   public static void main(String[] args) throws Exception
>>   {
>>     ClassLoader cl = new ClassLoader(null) { };
>>     System.out.println(cl.loadClass("java.lang.Object"));
>>     System.out.println(cl.loadClass("test"));
>>   }
>> }
>>
>> The cl ClassLoader will only load bootstrap classes. If you run this the result is:
>> class java.lang.Object
>> Exception in thread "main" java.lang.ClassNotFoundException: test
>>         at java.lang.ClassLoader.findClass(ClassLoader.java:359)
>>         at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
>>         at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
>>         at test.main(test.java:7)
>
> yes, but is that specified?
>
> bye Jochen
>

How well do you want it specified? JLS?

http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html#loadClass(java.lang.String,%20boolean)

That's the best I've found. How likely is it for that to be changed in
a future release, given Sun's stance on backward compatibility?

Cheers,

James

Jochen Theodorou

unread,
Apr 16, 2009, 4:34:13 PM4/16/09
to jvm-la...@googlegroups.com
James Abley schrieb:
[...]

> How well do you want it specified? JLS?
>
> http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html#loadClass(java.lang.String,%20boolean)
>
> That's the best I've found. How likely is it for that to be changed in
> a future release, given Sun's stance on backward compatibility?

hmm... it says if the parent is null, then the VM built in class loader
will be used. Could it be, that the docs are not very well in that area?
Or is it clear, that the built in class loader is the bootstrap
loader? I think I did read somewhere that in Java 1.1.x the bootstrap
loader did also load classpath elements. And since 1.2 this has been
changed. But I worry not so much because of the Sun VM, I worry more
about if other VMs do that the same way or not

Rémi Forax

unread,
Apr 16, 2009, 5:10:49 PM4/16/09
to jvm-la...@googlegroups.com
Just to blur the image a little bit more,
you can take a look to section 5.3.1 of JVMS
http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#79383

"The bootstrap class loader can delegate the loading of C to some
user-defined class loader L
by passing N to an invocation of a |loadClass| method on L.
The result of the invocation is C. The Java virtual machine then records
that the bootstrap loader
is an initiating loader of C (§5.3.4)
<http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#78621>.
"

Rémi

Jochen Theodorou a écrit :

Jeroen Frijters

unread,
Apr 17, 2009, 12:31:18 AM4/17/09
to jvm-la...@googlegroups.com
Jochen Theodorou wrote:
> Sent: Thursday, April 16, 2009 20:58
> To: jvm-la...@googlegroups.com
> Subject: [jvm-l] Re: bootstrap class loader

>
>
> Jeroen Frijters schrieb:
> > Hi Jochen,
> >
> > Maybe I'm misunderstanding you, but isn't it as simple as this:
> >
> > public class test
> > {
> > public static void main(String[] args) throws Exception
> > {
> > ClassLoader cl = new ClassLoader(null) { };
> > System.out.println(cl.loadClass("java.lang.Object"));
> > System.out.println(cl.loadClass("test"));
> > }
> > }
> >
> > The cl ClassLoader will only load bootstrap classes. If you run this
> the result is:
> > class java.lang.Object
> > Exception in thread "main" java.lang.ClassNotFoundException: test
> > at java.lang.ClassLoader.findClass(ClassLoader.java:359)
> > at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> > at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
> > at test.main(test.java:7)
>
> yes, but is that specified?

No, it isn't. There isn't any specified way to do what you want, because the whole notion of a bootstrap class loader is under specified. I'm pretty sure it's legal for a VM to have no bootstrap class loader (i.e. only a system class loader). But in that case you can't make the distinction anyway, so for most scenarios the above should do what you want (unless you absolutely need to prevent loading "user" classes, in which case you should fail to run on a VM that doesn't make a distinction between "user" and "system" classes).

Regards,
Jeroen

Reply all
Reply to author
Forward
0 new messages