RE: RE: RE: Problems with class loader

2002-09-10 Thread Cox, Charlie

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

2002-09-06 Thread Juergen . Praska

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

2002-09-06 Thread Rodrigo Ruiz

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

2002-09-05 Thread Juergen . Praska

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

2002-09-05 Thread Cox, Charlie



 -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

2002-08-30 Thread Cox, Charlie

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

2002-08-30 Thread Craig R. McClanahan



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

2002-08-29 Thread Juergen . Praska

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

2002-08-09 Thread Cox, Charlie

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

2002-08-09 Thread Juergen . Praska

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]