tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Cox, Charlie" <c...@cincom.com>
Subject RE: RE: RE: Problems with class loader
Date Thu, 05 Sep 2002 12:55:55 GMT


> -----Original Message-----
> From: Juergen.Praska@gmx.de [mailto:Juergen.Praska@gmx.de]
> Sent: Thursday, September 05, 2002 5:51 AM
> To: tomcat-user@jakarta.apache.org
> Subject: RE: RE: RE: Problems with class loader
> 
> 
> Hi Charlie,
> 
> You are right saying that it is a consequence of how classes 
> are loaded....
> Still, this can be an error... ;-)
> 
> I think I could live with the fact that as long as the 
> "container" of the
> serialized classes was just a HashTable.  This would, of 
> course, require
> that I always keep the current version of the HashTable.class 
> file in my
> application (where is definitely does not belong: but we 
> agree on this)..
> 
> What makes me feel a little unconfortable is the following: I 
> can readily
> do something like this:
> 
>    hashTable.add(new PrivateInfo());
> 
> but I cannot do:
> 
>    hashTable.add(new PrivateInfo());
>    hashTable = deserialize(serialize(hashTable));
> 
> just a few lines later (which should almost be a no-op).  Though I can
> explain this because I know what happens in detail, I have a 
> hard time to
> explain this to someone who is not into so many technical 
> details as we
> are...
> 
> What I would expect from this code is the following: when an 
> Object is read
> off a stream, the classloader in charge should be the application
> classloader.  
And this is what happens when the Hashtable is in the WebApp because the
Hashtable is calling Class.loadClass() for the serialized class and since
both the Hashtable and PrivateInfo are in the WebApp, the classloader is
happy. 

Anytime you have your own classloader, you will have this problem since the
Hashtable by default is in the jvm's bootstrap and not loaded in your
classloader. The child classloader has no problem finding the Hashtable and
the Hashtable can store an object because it is not creating any objects.
Once you intorduce serializtion and hashtable needs to create classes, it
will not know about any child classloaders' classes.


> The same classloader should be loading and 
> instantiating all
> remaining classes.  This way, I would behave the same as 
> having written the
> instantiation code myself.
> 

As long as the same clssloader that creates Hashtable can create
PrivateInfo, you should be fine.


> Having written this, I just realized that this could break 
> code: I some
> common library would depend on knowing that some of its 
> dependend classes
> are loaded by the same classloader, and the same class - 
> well, not really
> the same, but rather similar, but with the same name - would 
> be also part
> of the application, we would break existing code. :-(
> 
> Conclusion for the time being: the topic is (1) compex, (2) 
> difficult, (3)
> not so easy to come by as hoped/expected.  This is a small deployment
> nightmare! :-)

agreed, agreed, and unfortunately agreed. 

> 
> I have to admit: I'm stuck and clue-less as to how to go on... :-(
>

So outside of moving hashtable to the WebApp or moving PrivateInfo to the
JVM bootstrap(a little better than moving hashtable around), what other
problems do you have/foresee?

You can have PrivateInfo in the JVM's bootstrap and the webapps will be able
to see it, but it will not be able to see other webapp classes. If
PrivateInfo is just a data class and you can work with that restriction,
then go for it.
Two other restictions in this case also: 
(1) You can not have multiple versions of PrivateInfo for different webapps
and have serialization work as you expect it.
(2) Any static declarations are shared between all webapps.

I think this is workable, just not the ideal situation.

Charlie
 
> 
> Jürgen
> 
> --------------------------------------------------------------
> ------------
> From: ccox@cincom.com
> To: tomcat-user@jakarta.apache.org
> Date: Fri, 30 Aug 2002 11:24:14 -0400
> Subject: RE: RE: RE: Problems with class loader
> 
> I guess I wouldn't consider it a bug, but rather a consequence of how
> classes are loaded and which class loader holds the files in question.
> But I see your point in that you don't want Hashtable(and 
> more) in all your
> webapps...
> 
> you can open a bug for this and one of the developers(I'm not 
> a developer)
> will look at it. Feel free to include my responses and I will 
> help best I
> can.
> 
> To restate, the classes stored in the Hashtable(and 
> Vector,etc) would have
> to be in the same classloader as the Hashtable(and Vector,etc) when
> serializing a class containing a Hashtable.
> 
> Classloaders can only delegate requests to one 'parent'. So the common
> classloader either delegates to the 'system' 
> classloader(which it does) or
> to the 'webapp' classloader(then which one of those?)
> 
> I guess you would need to provide more detail as to why this 
> would still be
> a problem for you. Other than having the java 
> classes(Hashtable,etc) in
> your
> webapp instead of in the JVM's Bootstrap and having to 
> maintain this with
> each JVM upgrade, I don't see why this wouldn't work.
> 
> You *may* be able to move classes that will be in the hashtable to the
> /jre/lib/ext directory for your JVM, but that's not ideal 
> either as they
> won't be able to see your other classes loaded by tomcat, but 
> those classes
> loaded by tomcat will see them.
> 
> Charlie
> 
> > -----Original Message-----
> > From: Juergen.Praska@gmx.de [mailto:Juergen.Praska@gmx.de]
> > Sent: Thursday, August 29, 2002 11:05 AM
> > To: tomcat-user@jakarta.apache.org
> > Subject: RE: RE: RE: Problems with class loader
> >
> >
> > Hi Charlie,
> >
> > I gave it a try.  And guess what: it worked!  Now, in this
> > very simple case
> > one can argue that adding the collection classes to the
> > application's lib
> > directory is not a bad thing to do.  But what would one do if
> > the scenario
> > wasn't that simple? (Actually, it isn't!)
> >
> > Anyway, I consider this still a bug in the classloader hierarchy!
> >
> > So, where do we go from here?
> >
> >
> > --- Jürgen
> >
> > NB: As for your concerns with loading the classes more than
> > once: I think
> > that's what classloaders are for: I would always let it be
> > their problem... ;-)
> >
> > NB(2): Actually, the problem already shows up when an application is
> > serializing a hashtable that contains an object of a class
> > that is defined in the
> > application only. - Yet one reason why I think that's a bug
> > in the classloader
> > hierarchy.
> >
> > ----------- original post ------------
> >
> > ok, StandardClassLoader means that the class is trying to be
> > loaded from
> > \tomcat\lib. If it were being loaded from \web-inf\lib, it would be
> > WebappClassLoader throwing the error.
> >
> > >From your stack trace, it looks as if it is loading the Hashtable
> > ok(through
> > reflection), but it is the contents of the hashtable that
> > can't be loaded.
> > This would make sense since you put the Hashtable in \tomcat\lib.
> >
> > How about if you try to put Hashtable in the \web-inf\lib so
> > that the first
> > reflection call will find it in the current(webapp)
> > classloader, then the
> > second reflection call(from hashtable) will occur in your webapp's
> > classloader. Of course being a java class, I'm not sure if it
> > will have
> > problems being(or can be) loaded multiple times.
> >
> > Charlie
> >
> > > -----Original Message-----
> > > From: Juergen.Praska@gmx.de [mailto:Juergen.Praska@gmx.de]
> > > Sent: Friday, August 09, 2002 9:07 AM
> > > To: tomcat-user@jakarta.apache.org
> > > Subject: RE: RE: Problems with class loader
> > >
> > >
> > > see intermixed, too
> > >
> > > From: ccox@cincom.com
> > > To: tomcat-user@jakarta.apache.org
> > > Date: Fri, 9 Aug 2002 08:42:05 -0400
> > > Subject: RE: Problems with class loader
> > >
> > > see intermixed
> > >
> > > >
> > > > Hello,
> > > >
> > > > we have problems with the tomcat class loaders.
> > > >
> > > > scenario:
> > > > Tomcat 4.0.4, jdk1.3
> > > > 2 Applications
> > > >
> > > > App1:webapps/App1/WEB-INF/lib/x.jar
> > > > App2:webapps/App2/WEB-INF/lib/x.jar (the same .jar-file)
> > > >
> > > > x.jar: a.class, b.class, c.class
> > > >
> > > > b.class has a Hashtable
> > (com.sun.java.util.collections.Hashtable) as
> > > > member-variable. (Hashtable is in the directory
> > > $CATALINA_HOME/lib/).
> > >
> > > why is hashtable defined in $CATALINA_HOME/lib ? Is there a
> > reason why
> > > allowing the JVM to provide the java classes is a problem?
> > > This shouldn't
> > > really matter in this case, but could cause problems keeping
> > > in sync with
> > > the current JVM version.
> > > --> yes, this jar-file doesn't have to defined there but this
> > > is not the
> > > problem
> > >
> > > > In the Hastable are Objects of the c.class.
> > > >
> > > > class a in App1 serialize class b and save it in persistence
> > > > (poet-)classes
> > > > in directory ($CATALINA_HOME/lib/).
> > > so, this poet(I'm not familiar with it) is located in
> > > $CATALINA_HOME/lib ?
> > > Is this the class that tries to create an instance of b.class?
> > > --> no, class a in x.jar tries to create an instance with the
> > > ObjectInputStream
> > >
> > > If so this is your problem. Classes in the /tomcat/lib or
> > > /common/lib can
> > > *NOT* see classes in the /web-inf/lib directories. Try
> > moving x.jar to
> > > /tomcat/lib and see if it fixes your problem.
> > > --> I can`t do it because there are dependances to other
> > > classes in the
> > > application-directory.
> > >
> > > Alternatively you could move poet to each web-inf/lib with
> > > x.jar, but they
> > > need to stay together.
> > > --> this is also impossible because the poet-classes can only
> > > be loaded from
> > > one class loader.
> > >
> > > jürgen
> > >
> > > Charlie
> > >
> > > > In App2 class a load the serialized class from the
> > > > persistence classes and
> > > > deserialize it (--> class b).
> > > > Then, a ClassNotFoundException (class c) is thrown (see
> > > lower). Why???
> > > >
> > > > class b and the Hashtable are loaded, but not class c.
> > > >
> > > > It is as follows: ?
> > > > The applicationClassLoader finds the class b and then the
> > > > StandardClassLoader finds the Hashtable and then (however??) the
> > > > StandardClassLoader try to load class c. And of course the
> > > > class loader
> > > > can't find the class c!
> > > >
> > > >
> > > > thanks
> > > > jürgen
> > > >
> > > >
> > > >  at
> > > > org.apache.catalina.loader.StandardClassLoader.loadClass(Stand
> > > > ardClassLoade
> > > > r.java:1127)
> > > >  at
> > > > org.apache.catalina.loader.StandardClassLoader.loadClass(Stand
> > > > ardClassLoade
> > > > r.java:992)
> > > >  at 
> java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
> > > >  at java.lang.Class.forName0(Native Method)
> > > >  at java.lang.Class.forName(Class.java:195)
> > > >  at
> > > java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:654)
> > > >  at
> > > > java.io.ObjectInputStream.inputClassDescriptor(ObjectInputStre
> > > > am.java:918)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:366)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)
> > > >  at
> > > java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1186)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:386)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)
> > > >  at
> > > >
> > >
> > 
> com.sun.java.util.collections.Hashtable.readObject(Hashtable.java:773)
> > > >  at java.lang.reflect.Method.invoke(Native Method)
> > > >  at
> > > > java.io.ObjectInputStream.invokeObjectReader(ObjectInputStream
> > > > .java:2213)
> > > >  at
> > > java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1410)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:386)
> > > >  at
> > > > java.io.ObjectInputStream.inputClassFields(ObjectInputStream.j
> > > > ava:2262)
> > > >  at
> > > > java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.
> > > > java:519)
> > > >  at
> > > java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1411)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:386)
> > > >  at
> > java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)
> 
> -- 
> GMX - Die Kommunikationsplattform im Internet.
> http://www.gmx.net
> 
> 
> --
> To unsubscribe, e-mail:   
> <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: 
> <mailto:tomcat-user-help@jakarta.apache.org>
> 

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


Mime
View raw message