tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Herrmann, Sascha \(GE Healthcare\)" <Sascha.Herrm...@med.ge.com>
Subject RE: WebappClassLoader - don't understand what's happening
Date Fri, 03 Jun 2005 16:54:41 GMT
Well, it seems that the shared classes in shared\lib really are responsible
for this. I tried to move those in the WEB-INF\lib directories. There are a 
couple of new problems to work out, nothing serious, but the problem with the "shared" classes
vanished.

Thanks again for your assistance.

> did lose my mind in the maze of classloading several time.

I know what you mean :o)

Sascha


> -----Original Message-----
> From: delbd [mailto:delbd@oma.be] 
> Sent: Thursday, June 02, 2005 4:02 PM
> To: Tomcat Users List
> Subject: Re: WebappClassLoader - don't understand what's happening
> 
> Le Jeudi 2 Juin 2005 14:50, Herrmann, Sascha (GE Healthcare) a écrit :
> > > Any library having static methods like 
> SomeLibraryClass.setXYZ(xyz); 
> > > SomeLibraryClass.getXYZ(xyz);
> >
> > Wow, wow, wow .... . You mean any class that has static 
> methods gets 
> > shared?? Any class that calls static methods? Could you 
> explain that a 
> > bit further, please?
> >
> 
> No, i mean a shared class which has static methods could 
> potentially serves as a bridge for objects between web 
> applications :) I forgot the 'shared' in the sentence 'Any 
> shared library having static methods', sorry ;)
> 
> > > so i doubt usefull informations comes from it.
> >
> > It works for all the other methods I put this code in. It 
> seems that 
> > Tomcat assigns the CL to thread when it's fetched from the pool.
> 
> Possible, might have a sense in terms of security.
> 
> >
> > It's definitely the case. We have a static log variable in the 
> > classes. It holds the log4j logger reference. All the debug output 
> > from the class goes into the log file of the application 
> that started 
> > first (the one that loaded the class). Even the output when 
> I use the 
> > app that was started second. That's how I noticed in the 
> first place.
> >
> 
> is log4j a shared lib? if this is the case, might explain why 
> all logs are in one common file (see log4j explanations for 
> details, it's stated log4j should be put in WEB-INF/lib and 
> nowhere else to prevent problems in J2EE environnement). In 
> your case, this simply mean the config is shared, like is the 
> log4j libraries. 
> Don't mis this point: static Logger 
> Logger.getLogger(SomeClass.class), does not mean the logger 
> is 'the one for the class' but this mean the Logger is 'the 
> one having the name some.package.SomeClass' this difference 
> is subtle but has lots of implications when several different 
> classes with excaclty the same name and package are using a 
> common Log4j library.
> 
> > Are you familiar with the classloading stuff?
> >
> 
> did lose my mind in the maze of classloading several time.
> 
> > I was wondering ... when the WebappClassLoader doesn't find 
> the class 
> > in its path, and then delegates the loading to the shared 
> classloader 
> > ... and when then the shared classloader loads the class .... who 
> > resolves the dependecies of this loaded class? Does the 
> > WebappClassLoader get a shot first, or is it still the 
> shared classloader?
> 
> when the shared class loader loads a class in the delegation 
> model, it assigns itself to the class.getClassLoader(). That 
> is any other class further loaded by object of the first 
> class will be loaded using the shared classloader. 
> This is the excpected behaviour. So in your question, the 
> answer is "no the WebappClassLoader is not given a chance to 
> resolve as shared classloader does not know it's childrens"
> 
> >
> > What if the shared classloader loads a class, and then 
> cannot resolve 
> > a referenced class (because it's in one of the app's WEB-INF\lib 
> > directories)
> 
> the sharedclassloader is unable to load anything in 
> WEB-INF/lib, because it doesn't know about it.
> So in your case, it will ask it's parent (probably the JVM 
> classLoader) which will throw a ClassNotFoundException
> 
> 
> > ... how does he determine which child WebappClassLoader he 
> is to use? 
> > And who is registered in the JVM then as initiating classloader?
> 
> The delegation model goes down - top (from the calling class' 
> classloader to the root classloader), it nevers goes back 
> down later. A class instanciated by the shared classloader, 
> is *never* able to load any class from a WEB-INF/lib using 
> Class.forName()
> 
> >
> > I am asking because we have classes in our shared\lib 
> directory. Those 
> > classes use a factory pattern to instantiate classes (that 
> can be in 
> > the WEB-INF\lib dirs). Now, I wonder how these classes are loaded, 
> > that the factory class in shared\lib needs?
> 
> Sorry but if factories are in shared/lib, they are unable to 
> load anything from WEB-INF/lib .... with one exception, if 
> they are passed as argument the classloader of the 
> WEB-INF/lib to use, they can use it to instanciate the class. 
> But this is not a suggested way to write factories.
> However, a better behaviour would anyway be to put those 
> factories in WEB-INF/lib insteed of shared/lib
> 
> >
> > Or am I thinking in the wrong direction? Does the WebappClassLoader 
> > always try first?
> >
> > Damn, I wish I would know this classloading stuff better.
> 
> We all learned the way they work the hardway ;) and yes you 
> are thinking in the wrong direction, you think the delegation 
> model is a 2 way path. This is not, it's a no return path.
> 
> >
> > Do you have an idea why I cannot get logging output from the 
> > WebappClassLoaderS?
> 
> see messages above. ;)
> 
> >
> > Sascha
> >
> > > -----Original Message-----
> > > From: delbd [mailto:delbd@oma.be]
> > > Sent: Thursday, June 02, 2005 2:32 PM
> > > To: Tomcat Users List
> > > Subject: Re: WebappClassLoader - don't understand what's happening
> > >
> > > Le Jeudi 2 Juin 2005 13:49, Herrmann, Sascha (GE 
> Healthcare) a écrit :
> > > > Thanks for your reply.
> > > >
> > > > It could be. How is a class "pushed" to a shared library?
> > >
> > > Any library having static methods like 
> SomeLibraryClass.setXYZ(xyz); 
> > > SomeLibraryClass.getXYZ(xyz);
> > >
> > > > I used the following code:
> > > >
> > > >       System.out.println( "BoneDBTransactionImpl2  LOADING 
> > > > ***************************************" ); System.out.println( 
> > > > "Thread Classloader is: " +
> > > > Thread.currentThread().getContextClassLoader() );
> > >
> > > System.out.println(
> > >
> > > > "Hash: " +
> > > > Thread.currentThread().getContextClassLoader().hashCode() ); 
> > > > System.out.println( "Class: " +
> > >
> > > 
> Thread.currentThread().getContextClassLoader().getClass().getName() 
> > > );
> > >
> > > > System.out.println( "---------------------------     " );
> > > >       System.out.println( "Class Classloader is: " +
> > > > BoneDBTransactionImpl2.class.getClassLoader() );
> > >
> > > System.out.println( "Hash:
> > > > " + BoneDBTransactionImpl2.class.getClassLoader().hashCode() ); 
> > > > System.out.println( "Class: " +
> > >
> > > 
> BoneDBTransactionImpl2.class.getClassLoader().getClass().getName() 
> > > );
> > >
> > > > System.out.println( "BoneDBTransactionImpl2  LOADING 
> > > > ***************************************" );
> > >
> > > Tss tss tss, the Threads instances are started by 
> catalina-http and 
> > > shared inside a Thread pool amongst tomcat application if am not 
> > > wrond, so i doubt usefull informations comes from it.
> > > Only usefull information should comes from
> > > BoneDBTransactionImpl2.class.getClassLoader() as this is the 
> > > classloader which will load any class needed by 
> > > BoneDBTransactionImpl2.
> > >
> > > > I put this into a static initializer block of a class that
> > >
> > > is in a jar
> > >
> > > > in both WEB_INF\lib directories. I also added this code the 
> > > > constructor of that class. And to make sure to see what
> > >
> > > loader belongs
> > >
> > > > to what app I also added the code to some methods of
> > >
> > > classes that are
> > >
> > > > either in app A or in app B and not in both.
> > > >
> > > > I start app A. The output shows that
> > > >
> > > > - the class is loaded in app A by WebappClassLoader with hash A
> > > > - the instance is created in app A using the Class loaded by 
> > > > WebappClassLoader with hash A. - Thread context classloader is 
> > > > WebappClassLoader with hash A.
> > > >
> > > > Then I start app B. The output shows that
> > > >
> > > > - the instance is created in app B using the Class loaded by 
> > > > WebappClassLoader with hash A - Thread context classloader is 
> > > > WebappClassLoader with hash B.
> > >
> > > Strange indeed, so you mean when starting app B, the 
> static block of
> > > BoneDBTransactionImpl2 is never executed? If that's the case this 
> > > indeed mean the class was already loaded before. Either this mean 
> > > you have another lib in webapp B requiring
> > > BoneDBTransactionImpl2 and you didn't see the static init 
> message 50 
> > > lines before ;), either you indeed have something shared.
> > >
> > > One easy way to check
> > > In webapp A, create a servelt which will set to 1 a 
> static boolean 
> > > in
> > > BoneDBTransactionImpl2 and in webapp B, set another servlet which 
> > > will read the value of this boolean.
> > > first access B servlet to ensure boolean is set to false acces A 
> > > servlet to switch boolean to true re-access B servlet to check if 
> > > boolean has switched value in B webapp
> > >
> > > If that's the case, this really mean class is shared by 
> webapp class 
> > > loaders, serious problems ahead for tomcat team ;)
> > >
> > > > The class exists in jar files in both WEB-INF\lib
> > >
> > > directories, but not in
> > >
> > > > any other lib directory. And - if the class was loaded 
> by a shared 
> > > > classloader, shouldn't the xxx.class.getClassLoader() 
> return the 
> > > > StandardClassLoader?
> > >
> > > dunno
> > >
> > > > I must admit that I am not too familiar with the deeper
> > >
> > > concept of J2EE
> > >
> > > > classloading apart from the information found on some web pages.
> > >
> > > me too ;) however, separation in webapps mean every 
> ressource in a 
> > > .war is not to be shared with any other webapp.
> > >
> > > > So, if the class indeed is loaded by WebappClassLoader A,
> > >
> > > how can it be
> > >
> > > > "pushed" to become a shared one? And how can I prevent this
> > >
> > > from happening?
> > >
> > > > Or am I making a mistake reading the output? I am sure that
> > >
> > > the class is
> > >
> > > > not loaded again.
> > >
> > > see message above, i just didn't know how you concluded the class 
> > > was shared, one common error is to give an instance of 
> some object 
> > > to a shared library and retreive it in another webapp, not 
> > > understanding this object you are manipulating is a 
> stranger ;) not 
> > > your case scenario you describe.
> > >
> > > > I checked the sources in Apache's CVS. I noticed that there
> > >
> > > is quite some
> > >
> > > > debugging put into WebappClassLoader. But I can't get my
> > >
> > > server to log
> > >
> > > > these messages. I have the log4j and commons logging jars
> > >
> > > in my common\lib
> > >
> > > > directory and my log4j.properties (root logger set to 
> debug) in my 
> > > > common\classes directory. I also set the debug to "4"
> > >
> > > everywhere in my
> > >
> > > > server.xml. I see some catalina debug messages, but I 
> cannot see 
> > > > the messages from the WebappClassLoader. So what am I doing
> > >
> > > wrong? I believe
> > >
> > > > the debug output would be very helpful in understanding 
> the problem.
> > >
> > > Yes have same problem here to get usefull log messages 
> from Realms. 
> > > Seems you have to modify directly the logging level in your java 
> > > home, logging.properties (and setting it to debug for 
> whole jvm is 
> > > VERY verbose)
> > >
> > > > Sascha
> > > >
> > > > > -----Original Message-----
> > > > > From: delbd [mailto:delbd@oma.be]
> > > > > Sent: Thursday, June 02, 2005 12:33 PM
> > > > > To: Tomcat Users List
> > > > > Subject: Re: WebappClassLoader - don't understand what's 
> > > > > happening
> > > > >
> > > > > This indeed should not happen as this would break sun specs.
> > > > > I would be quite surprised it it was at all possible 
> :/ How did 
> > > > > you conclude the webappclassloader is sharing the 
> class between 
> > > > > webapps in your case?
> > > > >
> > > > > Are you sure you are not mistakenly using a shared class?
> > > > >
> > > > > Not only does every webapp has his very own 
> webappclassloader, 
> > > > > but if you reload the webapp (using the manager/html 
> interface) 
> > > > > this should also create a new webclassloader and reload all 
> > > > > classes (did you check it was the case?).
> > > > >
> > > > > Am also using tomcat 5.5.7 here, with jdk 1.4.2_05-b04 and we 
> > > > > didn't notice such a problem. We can deploy several 
> webapps, all 
> > > > > using a library in WEB-INF/lib which is crating 
> singletons. All 
> > > > > webapp has it's own sets of singletons.
> > > > >
> > > > > Could it be that you are in fact doing such scenario?
> > > > >
> > > > > - create an object of class A in webapp1 using 
> > > > > webappclassloader1
> > > > > - push this object to some library shared between 
> > > > > webapplications
> > > > > - retrieve the object from shared library in webapp2 
> (as this is 
> > > > > via a shared library, it's possibile to do and you and up 
> > > > > manipulating in webapp2 an object who's classloader is
> > > > > webappclassloader1)
> > > > > - in webapp2, calls something like a.createB() to get 
> an object 
> > > > > of class B and be surprised that the class of B was created 
> > > > > using webappclassloader1
> > > > >
> > > > > Le Jeudi 2 Juin 2005 10:59, Herrmann, Sascha (GE
> > >
> > > Healthcare) a écrit :
> > > > > > We are facing a problem with Tomcats WebappClassLoader.
> > > > > > We deploy several of our own applications on one 
> Tomcat server.
> > > > > >
> > > > > > It seems that the WebappClassLoaderS are not isolated but 
> > > > > > share classes instead. Why would that be?
> > > > > >
> > > > > > Judging from the (well, outdated) classloader
> > >
> > > documentation, this
> > >
> > > > > > should never happen.
> > > > > > If an application tries to use a class, and the class is in
> > > > >
> > > > > a jar in
> > > > >
> > > > > > its WEB_INF\lib directory, then the class should be
> > >
> > > loaded by the
> > >
> > > > > > application's very own WebappClassLoader. It should not be
> > > > >
> > > > > available
> > > > >
> > > > > > to other WebappClassLoaderS, isn't that correct? I quote:
> > > > > >
> > > > > > "All unpacked classes and resources in the /WEB-INF/classes
> > > > >
> > > > > directory
> > > > >
> > > > > > of your web application archive, plus classes and
> > >
> > > resources in JAR
> > >
> > > > > > files under the /WEB-INF/lib directory of your web 
> application 
> > > > > > archive, are made visible to the containing web
> > > > >
> > > > > application, **but to no others**."
> > > > >
> > > > > > Instead of sharing the class, the second WebappClassLoader
> > > > >
> > > > > should load
> > > > >
> > > > > > the class again, shouldn't it?
> > > > > > So why does a WebappClassLoader here re-use a class already
> > > > >
> > > > > loaded by
> > > > >
> > > > > > the WebappClassLoader of another application?
> > > > > >
> > > > > > We're running 5.5.7 on JDK 142_08.
> > > > > >
> > > > > > Thanks in advance!
> > > > > >
> > > > > >
> > > > > > Sascha Herrmann
> > > > > > Engineering (Java)
> > > > > > GE Healthcare
> > > > > > Technologies
> > >
> > > 
> --------------------------------------------------------------------
> > > -
> > >
> > > > > > To unsubscribe, e-mail:
> > >
> > > tomcat-user-unsubscribe@jakarta.apache.org
> > >
> > > > > > For additional commands, e-mail:
> > >
> > > tomcat-user-help@jakarta.apache.org
> > >
> > > > > --
> > > > > David Delbecq
> > > > > Royal Meteorological Institute of Belgium
> > > > >
> > > > > -
> > > > > Is there life after /sbin/halt -p?
> > >
> > > 
> --------------------------------------------------------------------
> > > -
> > >
> > > > > To unsubscribe, e-mail: 
> > > > > tomcat-user-unsubscribe@jakarta.apache.org
> > > > > For additional commands, e-mail:
> > >
> > > tomcat-user-help@jakarta.apache.org
> > >
> > >
> > > 
> --------------------------------------------------------------------
> > > -
> > >
> > > > To unsubscribe, e-mail: 
> tomcat-user-unsubscribe@jakarta.apache.org
> > > > For additional commands, e-mail: 
> > > > tomcat-user-help@jakarta.apache.org
> > >
> > > --
> > > David Delbecq
> > > Royal Meteorological Institute of Belgium
> > >
> > > -
> > > Is there life after /sbin/halt -p?
> > >
> > > 
> --------------------------------------------------------------------
> > > - To unsubscribe, e-mail: 
> tomcat-user-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail: 
> tomcat-user-help@jakarta.apache.org
> >
> > 
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
> 
> --
> David Delbecq
> Royal Meteorological Institute of Belgium
> 
> -
> Is there life after /sbin/halt -p?
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Mime
View raw message