RE: RE: RE: Problems with class loader
Glad I could help! I enjoyed the discussion as well. I like the challenging problems :) sorry for the late response, I was out of the office. Charlie -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Friday, September 06, 2002 3:15 AM To: [EMAIL PROTECTED] Subject: RE: RE: RE: Problems with class loader Hi Charlie, thanks for your mail. After some heavy thinking (gee, this topic lasted longer than expected! :-) ), we came to the following conclusion: We will copy the HashTable.class to the application library. We believe this is the best we can do because (1) we maintain the concept of storing all classes, libraries and information as close as possible to the application itself, (2) even if HashTable.class changes between different JDKs, we have to watch only this happen (i.e., the change of the JDK). Now, this will happen, say, once every other year ;-) (3) the other alternatives we were discussing are not applicable because the expose too much code to too many classloaders. The good thing is: we can be somewhat sure that the only class other than our own classes is HashMap.class. Also, if necessary, we can copy the JRE libs to the application. I think this concludes this discussion. Thanks a lot for the discussion we had. I enjoyed it very much! Jürgen -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, September 05, 2002 5:51 AM To: [EMAIL PROTECTED] 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
RE: RE: RE: Problems with class loader
Hi Charlie, thanks for your mail. After some heavy thinking (gee, this topic lasted longer than expected! :-) ), we came to the following conclusion: We will copy the HashTable.class to the application library. We believe this is the best we can do because (1) we maintain the concept of storing all classes, libraries and information as close as possible to the application itself, (2) even if HashTable.class changes between different JDKs, we have to watch only this happen (i.e., the change of the JDK). Now, this will happen, say, once every other year ;-) (3) the other alternatives we were discussing are not applicable because the expose too much code to too many classloaders. The good thing is: we can be somewhat sure that the only class other than our own classes is HashMap.class. Also, if necessary, we can copy the JRE libs to the application. I think this concludes this discussion. Thanks a lot for the discussion we had. I enjoyed it very much! Jürgen -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, September 05, 2002 5:51 AM To: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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
Re: RE: RE: Problems with class loader
Just an idea: I would create a subclass of Hashtable, rewriting serialization code so it won't call Hashtable code. I mean something like this: private void writeObject(ObjectOutputStream out) throws IOException { out.writeInt(this.size()); for (Enumeration keys = this.keys(); keys.hasMoreElements(); ) { Object key = keys.nextElement(); Object value = this.get(key); out.writeObject(key); out.writeObject(value); } } and the opposite for the readObject method. This way, there is no object creation out of your webapp, while keeping the Hashtable interface (just take care in hashtable creation and deserialization code. The rest remains the same) It seems to me that copying JRE libs into the webapp will cause a very big memory overhead, as *ALL* core classes will be loaded twice in the JVM. Hope it helps :) Rodrigo - Original Message - From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, September 06, 2002 9:15 AM Subject: RE: RE: RE: Problems with class loader Hi Charlie, thanks for your mail. After some heavy thinking (gee, this topic lasted longer than expected! :-) ), we came to the following conclusion: We will copy the HashTable.class to the application library. We believe this is the best we can do because (1) we maintain the concept of storing all classes, libraries and information as close as possible to the application itself, (2) even if HashTable.class changes between different JDKs, we have to watch only this happen (i.e., the change of the JDK). Now, this will happen, say, once every other year ;-) (3) the other alternatives we were discussing are not applicable because the expose too much code to too many classloaders. The good thing is: we can be somewhat sure that the only class other than our own classes is HashMap.class. Also, if necessary, we can copy the JRE libs to the application. I think this concludes this discussion. Thanks a lot for the discussion we had. I enjoyed it very much! Jürgen
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. 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. 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! :-) I have to admit: I'm stuck and clue-less as to how to go on... :-( Jürgen -- From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, August 29, 2002 11:05 AM To: [EMAIL PROTECTED] 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
RE: RE: RE: Problems with class loader
-Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, September 05, 2002 5:51 AM To: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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
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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Thursday, August 29, 2002 11:05 AM To: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Friday, August 09, 2002 9:07 AM To: [EMAIL PROTECTED] Subject: RE: RE: Problems with class loader see intermixed, too From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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
RE: RE: RE: Problems with class loader
On Fri, 30 Aug 2002, Cox, Charlie wrote: Date: Fri, 30 Aug 2002 11:24:14 -0400 From: Cox, Charlie [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: 'Tomcat Users List' [EMAIL PROTECTED] 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... I'd consider it an unavoidable limitation of the class loading architecture of Java -- class loaders can look up but not down the hierarchy. However, there is hope for developers who want to put shared classes into something like common/lib, but still make it possible for those shared classes to load things from the webapp class loader. Your shared code has to be specifically programmed to do this, but at least it's possible. Consider the case where a shared code class wants to load class foo.Bar from the webapp class loader, and then create a new instance of that class. Modulo exception handling, do something like this: ClassLoader webappCL = Thread.currentThread().getContextClassLoader(); Class webappClass = webappCL.loadClass(foo.Bar); Bar bar = webappClass.newInstance(); The reason this works is that the servlet container always copies a reference to the webapp's class loader to the context class loader property of the request processing thread, immediately before calling your servlet. This is done precisely to support this kind of access. Of course, the class you load this way from webapp A will *not* be visible to webapp B (which uses a different class loader), so you can't use this mechanism to share classes from /WEB-INF/classes or /WEB-INF/lib across web applications. But you *can* access webapp classes from shared code. Craig McClanahan -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Friday, August 09, 2002 9:07 AM To: [EMAIL PROTECTED] Subject: RE: RE: Problems with class loader see intermixed, too From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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
RE: Problems with class loader
see intermixed -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Friday, August 09, 2002 8:15 AM To: [EMAIL PROTECTED] Subject: Problems with class loader 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. 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? 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. Alternatively you could move poet to each web-inf/lib with x.jar, but they need to stay together. 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:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: RE: Problems with class loader
see intermixed, too From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] 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:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- GMX - Die Kommunikationsplattform im Internet. http://www.gmx.net -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]