You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Michel Betancourt <mi...@gmail.com> on 2008/01/17 02:33:17 UTC

Tomcat 5.5 classloading behavior

Hi,

I am wondering if someone may be able to point me in the right direction
here...  after reviewing the J2SE spec, and the Servlet 2.4 Spec, its not
too clear whether circular dependecies  such as the one I am investigating
below are legal or supported by Tomcat.  Sun J2SE 5.0 classloader does not
seem to support such initialization although the Tomcat classloader (v5.5)
seems to an operation such as my example below.

An exert of the Java specification states:
12.4.2, #3 If initialization is in progress for the class or interface by
the current thread, then this must be a recursive request for
initialization. Release the lock on the Class object and complete normally.

Servlet 2.4 spec says that Classloaders need to follow the J2SE
specification.


So as I am investigating the Tomcat 5.5 classloader I am wondering if either
one of these situations are legal for Tomcat 5.5 or whether I should be
observing a ClassCircularityError... debugging my App shows the following
behavior:

Examples :

Class A {

static {
System.out.println(B.somefield); // debugger shows that A is checked and the
static block is invoked.  B is loaded which initializes B.somefield through
the constructor of A.
}


}

Class B {
public static final A somefield;
}

and/or circular dependecy from Parent static initializers

Class Parent {
static {
System.out.println(B.somefield); // debugger shows A is checked, Parent is
loaded which loads B which loads somefield through the constructor of class
"A"
}
}

Class A extends Parent {
}

Class B {
public static final A somefield;
}

Thanks in advance.

Best Regards,
Mich

Re: Tomcat 5.5 classloading behavior

Posted by Gabe Wong <ga...@ngasi.com>.
Johnny Kewl wrote:
>
> What language is this guy talking....  ha ha.
> This has got to be for a thesis or something.... or its attempted 
> suicide ;)
>
> ----- Original Message ----- From: "Michel Betancourt" 
> <mi...@gmail.com>
> To: <us...@tomcat.apache.org>
> Sent: Thursday, January 17, 2008 3:33 AM
> Subject: Tomcat 5.5 classloading behavior
>
>
>> Hi,
>>
>> I am wondering if someone may be able to point me in the right direction
>> here...  after reviewing the J2SE spec, and the Servlet 2.4 Spec, its 
>> not
>> too clear whether circular dependecies  such as the one I am 
>> investigating
>> below are legal or supported by Tomcat.  Sun J2SE 5.0 classloader 
>> does not
>> seem to support such initialization although the Tomcat classloader 
>> (v5.5)
>> seems to an operation such as my example below.
>>
>> An exert of the Java specification states:
>> 12.4.2, #3 If initialization is in progress for the class or 
>> interface by
>> the current thread, then this must be a recursive request for
>> initialization. Release the lock on the Class object and complete 
>> normally.
>
> You know what you should do... find a little custom class loader 
> example on the web and run it through a debugger.
> They look simple but when you actually watch them work, and how 
> reentrent the things are, this will hopefully all start to make sense.
>
> I think most guys havnt even started thinking about this... 
> ClassCircularityError Wow!.... dont trap that in my code ;)
>
> This is what I think.... the normal system classloader, and the tomcat 
> classloader when it comes to threads and reentrant code will
> behave exactly the same... the reason is that one class loader 
> inherets from another and thus one can expect the behavior to be similar.
> The only diffirence is where the tomcat classloader will look for jars 
> and class's.
>
> ie the same stuff is happening but when it comes time to find "Your 
> Class"... it will look for it in the web-app, after that i think
> its much of a muchness.
> Thats different because outside of web servlets... class loaders are 
> not allowed to work like that... they always ask the classloader
> "above" them if it has the class already, if not the parent class 
> loader tries to find it, and ONLY if it cant find it, will the "child" 
> classloader
> try and get it.
>
> If you watch a cl working you'll see that recursive request stuff 
> happenning... and I'm no academic, in plain talk it just means
> that all those dependencies must be gotten out of the way, before the 
> next thread can come in and ask for a class to load.
> So if A -> B -> C and thread one is busy with A, and thread 2 really 
> just wants C.... it has to wait, because otherwise
> C would load... and then A would eventually get to it and it would 
> load again because its already kicked off that recursive pattern.
> Then because C is waiting.... A will actually will have done it 
> already... and the cl will then just say... thread 2, you lucky, class 
> is loaded, you can go now.
>
> Normal CL or Tomcat.... no diffs.
>
> The other thing with these examples is that yes I guess it is possible 
> to be surprised in the way STATIC variables are inited in complex
> class structure... but remember is LOADING, not INSTANTIATING the 
> class, that comes later outside of the CL, so in most cases
> it not an issue one would even encounter.
>
> I dont think its possible to make an ClassCircularityError error with 
> a modern IDE... I dont think it will let you compile the code
>
> Class A extends A
>
> so if you actually making these classes and compiling them.... I dont 
> think its possible to simulate it without hacking byte code.
> .... be interesting to hear if anyone ever seen that.
>
> Thanks... I never ever thought about static variables before... and 
> I've never seen it in practical code.
> ie I think in normal code a programmer may go.... what the... I 
> thought static A was going to be 5, why is it 10, or whatever...
> and then eventually see the curcular RELATIONSHIP.... but I doubt that 
> would cause an error.
> If its compiling... I dont think you can break a classloader... short 
> of it just cant find the Jar....
>
> interesting things these classloaders... good luck.
> If its practical stuff... I can help you a little, heavy specs and 
> theory... you on your own ;)
Nice analysis Johnny. To add to your thought (even though slightly off 
topic) -
Yes there is a big difference between theory (specification) and 
practice (implementation).
So it may be confusing for someone starting off from the theoretical side.


-- 
Regards

Gabe Wong
NGASI AppServer Manager
JAVA AUTOMATION and SaaS Enablement
<a href=http://www.ngasi.com>http://www.ngasi.com</a>
NEW! 8.0 - Centrally manage multiple physical servers


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat 5.5 classloading behavior

Posted by Johnny Kewl <jo...@kewlstuff.co.za>.
What language is this guy talking....  ha ha.
This has got to be for a thesis or something.... or its attempted suicide ;)

----- Original Message ----- 
From: "Michel Betancourt" <mi...@gmail.com>
To: <us...@tomcat.apache.org>
Sent: Thursday, January 17, 2008 3:33 AM
Subject: Tomcat 5.5 classloading behavior


> Hi,
>
> I am wondering if someone may be able to point me in the right direction
> here...  after reviewing the J2SE spec, and the Servlet 2.4 Spec, its not
> too clear whether circular dependecies  such as the one I am investigating
> below are legal or supported by Tomcat.  Sun J2SE 5.0 classloader does not
> seem to support such initialization although the Tomcat classloader (v5.5)
> seems to an operation such as my example below.
>
> An exert of the Java specification states:
> 12.4.2, #3 If initialization is in progress for the class or interface by
> the current thread, then this must be a recursive request for
> initialization. Release the lock on the Class object and complete 
> normally.

You know what you should do... find a little custom class loader example on 
the web and run it through a debugger.
They look simple but when you actually watch them work, and how reentrent 
the things are, this will hopefully all start to make sense.

I think most guys havnt even started thinking about this... 
ClassCircularityError Wow!.... dont trap that in my code ;)

This is what I think.... the normal system classloader, and the tomcat 
classloader when it comes to threads and reentrant code will
behave exactly the same... the reason is that one class loader inherets from 
another and thus one can expect the behavior to be similar.
The only diffirence is where the tomcat classloader will look for jars and 
class's.

ie the same stuff is happening but when it comes time to find "Your 
Class"... it will look for it in the web-app, after that i think
its much of a muchness.
Thats different because outside of web servlets... class loaders are not 
allowed to work like that... they always ask the classloader
"above" them if it has the class already, if not the parent class loader 
tries to find it, and ONLY if it cant find it, will the "child" classloader
try and get it.

If you watch a cl working you'll see that recursive request stuff 
happenning... and I'm no academic, in plain talk it just means
that all those dependencies must be gotten out of the way, before the next 
thread can come in and ask for a class to load.
So if A -> B -> C and thread one is busy with A, and thread 2 really just 
wants C.... it has to wait, because otherwise
C would load... and then A would eventually get to it and it would load 
again because its already kicked off that recursive pattern.
Then because C is waiting.... A will actually will have done it already... 
and the cl will then just say... thread 2, you lucky, class is loaded, you 
can go now.

Normal CL or Tomcat.... no diffs.

The other thing with these examples is that yes I guess it is possible to be 
surprised in the way STATIC variables are inited in complex
class structure... but remember is LOADING, not INSTANTIATING the class, 
that comes later outside of the CL, so in most cases
it not an issue one would even encounter.

I dont think its possible to make an ClassCircularityError error with a 
modern IDE... I dont think it will let you compile the code

Class A extends A

so if you actually making these classes and compiling them.... I dont think 
its possible to simulate it without hacking byte code.
.... be interesting to hear if anyone ever seen that.

Thanks... I never ever thought about static variables before... and I've 
never seen it in practical code.
ie I think in normal code a programmer may go.... what the... I thought 
static A was going to be 5, why is it 10, or whatever...
and then eventually see the curcular RELATIONSHIP.... but I doubt that would 
cause an error.
If its compiling... I dont think you can break a classloader... short of it 
just cant find the Jar....

interesting things these classloaders... good luck.
If its practical stuff... I can help you a little, heavy specs and theory... 
you on your own ;)

> Servlet 2.4 spec says that Classloaders need to follow the J2SE
> specification.
>
>
> So as I am investigating the Tomcat 5.5 classloader I am wondering if 
> either
> one of these situations are legal for Tomcat 5.5 or whether I should be
> observing a ClassCircularityError... debugging my App shows the following
> behavior:
>
> Examples :
>
> Class A {
>
> static {
> System.out.println(B.somefield); // debugger shows that A is checked and 
> the
> static block is invoked.  B is loaded which initializes B.somefield 
> through
> the constructor of A.
> }
>
>
> }
>
> Class B {
> public static final A somefield;
> }
>
> and/or circular dependecy from Parent static initializers
>
> Class Parent {
> static {
> System.out.println(B.somefield); // debugger shows A is checked, Parent is
> loaded which loads B which loads somefield through the constructor of 
> class
> "A"
> }
> }
>
> Class A extends Parent {
> }
>
> Class B {
> public static final A somefield;
> }
>
> Thanks in advance.
>
> Best Regards,
> Mich
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat 5.5 classloading behavior

Posted by Michel Betancourt <mi...@gmail.com>.
Thanks for the reply.  This is tough to provide an example for.  Let me see
what I can work out.

On Jan 16, 2008 11:08 PM, Caldarale, Charles R <Ch...@unisys.com>
wrote:

> > From: Michel Betancourt [mailto:michelb0216@gmail.com]
> > Subject: Tomcat 5.5 classloading behavior
> >
> > its not too clear whether circular dependecies such as
> > the one I am investigating below are legal or supported
> > by Tomcat.
>
> Detection of circular dependencies is not the responsibility of any
> classloader, let alone a Java application such as Tomcat.  Such
> determination is done by the core JVM.
>
> > Sun J2SE 5.0 classloader does not seem to support such
> > initialization
>
> Neither of your examples involves a true circular dependency, and they
> both work fine for me on JDK 1.5 and 1.6.  Perhaps you can supply a real
> example.
>
>  - Chuck
>
>
> THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
> MATERIAL and is thus for use only by the intended recipient. If you
> received this in error, please contact the sender and delete the e-mail
> and its attachments from all computers.
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>


-- 
-Michel

RE: Tomcat 5.5 classloading behavior

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Michel Betancourt [mailto:michelb0216@gmail.com] 
> Subject: Tomcat 5.5 classloading behavior
> 
> its not too clear whether circular dependecies such as 
> the one I am investigating below are legal or supported
> by Tomcat.

Detection of circular dependencies is not the responsibility of any
classloader, let alone a Java application such as Tomcat.  Such
determination is done by the core JVM.

> Sun J2SE 5.0 classloader does not seem to support such
> initialization 

Neither of your examples involves a true circular dependency, and they
both work fine for me on JDK 1.5 and 1.6.  Perhaps you can supply a real
example.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org