You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@geronimo.apache.org by Shan Karthic <sh...@gmail.com> on 2006/09/13 22:38:24 UTC

Classloader Hierarchy and hidden-classes

I am using geronimo 1.1.1-rc3.  I am using the release candidate instead of
1.1 since 1.1.1 fixes GERONIMO-2125.

Is there anyway I can specify, for everything under the application
classloader (including child classloaders of the application classloader,
such as WAR classloaders), that the classes loaded by application class
loader are visible but not the ones loaded above the application
classloader?

I want to hide some classes loaded by the server inside my application.  If
I use hidden-classes I am able to hide the classes loaded by current
classloader's parents.  The problem I face is if I use hidden-classes at WAR
level it hides the same classes loaded by EAR/application classloader as
well.  If I use hidden-classes only at application level and not at WAR
level, it does not hide the classes loaded by the server from the WAR class
loader.  It looks like child classloaders do not know of hidden-classes
specified at parent classloader level.  Is there any reason it is so?

I started out trying to force my application to use its own log4j
configuration accessed through commons logging.  So I had to hide
org.apache.commons.logging, org.apache.log4j,
org.apache.geronimo.kernel.logloaded by the server.  An utility jar in
the application manages references
to Log objects.  The utility is used by EJBs and other utilities and WAR.

I am able to get the desired behaviour by hiding the classes at both app
level and at WAR level with inverse-classloading at WAR level.  If I do not
hide at WAR level, WAR class loader sees the classes loaded by the server.
If I hide at WAR level without inverse-classloading, WAR class loader does
not see log4j classes loaded by the app class loader.  But (I think so but
my interpretation of the diagnostic messages from commons logging may be
wrong), due to the way Log references are stored in a hierarchy of class
loaders, there seems to be assignments between log4j classes loaded by app
and WAR classloaders which results in errors.

Now the problem is, since I have enabled inverse-classloading at WAR level,
classes loaded by WAR classloader do not see any config/properties files
available under the EAR root.  I also think the singleton LogManager the
application uses is no longer singleton really as it is loaded separately by
the WAR and EAR classloaders.

As I see it, if I can hide the required classes at app classloader level,
that propagates to all child classloaders without hiding the classes loaded
the app classloader itself, that will help in resolving the problem.  I
searched but could not find whether there is anyway to do that.

Thanks and regards,
Shankar.

Re: Classloader Hierarchy and hidden-classes

Posted by David Jencks <da...@yahoo.com>.
I'm getting confused by your description, and looking at the code in  
trunk what I think you're saying doesn't look too likely... so I'm  
pretty sure I'm confused about something here and misunderstanding  
what you are saying.

Could you outline what you are seeing in terms of a class org.foo.X  
that is present in 3 classloaders:

cl1
parent of
cl2
parent of
cl3

where cl2 or cl3 has org.foo in hidden classes and either cl2 or cl3  
or maybe both have inverse classloading turned on?

Seems like maybe we need some test cases to make sure what we think  
is happening, is actually happening.

Many thanks
david jencks

On Sep 13, 2006, at 4:38 PM, Shan Karthic wrote:

> I am using geronimo 1.1.1-rc3.  I am using the release candidate  
> instead of 1.1 since 1.1.1 fixes GERONIMO-2125.
>
> Is there anyway I can specify, for everything under the application  
> classloader (including child classloaders of the application  
> classloader, such as WAR classloaders), that the classes loaded by  
> application class loader are visible but not the ones loaded above  
> the application classloader?
>
> I want to hide some classes loaded by the server inside my  
> application.  If I use hidden-classes I am able to hide the classes  
> loaded by current classloader's parents.  The problem I face is if  
> I use hidden-classes at WAR level it hides the same classes loaded  
> by EAR/application classloader as well.  If I use hidden-classes  
> only at application level and not at WAR level, it does not hide  
> the classes loaded by the server from the WAR class loader.  It  
> looks like child classloaders do not know of hidden-classes  
> specified at parent classloader level.  Is there any reason it is so?
>
> I started out trying to force my application to use its own log4j  
> configuration accessed through commons logging.  So I had to hide  
> org.apache.commons.logging, org.apache.log4j,  
> org.apache.geronimo.kernel.log loaded by the server.  An utility  
> jar in the application manages references to Log objects.  The  
> utility is used by EJBs and other utilities and WAR.
>
> I am able to get the desired behaviour by hiding the classes at  
> both app level and at WAR level with inverse-classloading at WAR  
> level.  If I do not hide at WAR level, WAR class loader sees the  
> classes loaded by the server.  If I hide at WAR level without  
> inverse-classloading, WAR class loader does not see log4j classes  
> loaded by the app class loader.  But (I think so but my  
> interpretation of the diagnostic messages from commons logging may  
> be wrong), due to the way Log references are stored in a hierarchy  
> of class loaders, there seems to be assignments between log4j  
> classes loaded by app and WAR classloaders which results in errors.
>
> Now the problem is, since I have enabled inverse-classloading at  
> WAR level, classes loaded by WAR classloader do not see any config/ 
> properties files available under the EAR root.  I also think the  
> singleton LogManager the application uses is no longer singleton  
> really as it is loaded separately by the WAR and EAR classloaders.
>
> As I see it, if I can hide the required classes at app classloader  
> level, that propagates to all child classloaders without hiding the  
> classes loaded the app classloader itself, that will help in  
> resolving the problem.  I searched but could not find whether there  
> is anyway to do that.
>
> Thanks and regards,
> Shankar.


RE: Classloader Hierarchy and hidden-classes

Posted by "Clough, Ray C PWR" <Ra...@pwr.utc.com>.
If I include commons-logging.jar in the WEB-INF/lib directory the app
won't load and throws a bunch of exceptions.  I got around it by having
ANT not include it in the EAR when I'm building for Geronimo.  I assumed
it was some shared classloader problem which doesn't meet the J2EE "one
class loader per app" spec.  I've run into that problem before with
other servers (specifically JRun).  Based on your reply, I'm assuming
that assumption was incorrect.  (I probably never heard what you do when
you 'assume'.)

- Ray Clough



-----Original Message-----
From: ammulder@gmail.com [mailto:ammulder@gmail.com] On Behalf Of Aaron
Mulder
Sent: Thursday, September 14, 2006 1:59 PM
To: user@geronimo.apache.org
Subject: Re: Classloader Hierarchy and hidden-classes

Can you define shared class loaders?  We don't share class loaders
across applications, and we don't appear to violate anything in J2EE (at
least, as far as the J2EE TCK is concerned).

What is your specific commons-logging problem?

Thanks,
     Aaron

On 9/14/06, Clough, Ray C             PWR <Ra...@pwr.utc.com>
wrote:
> commons-logging.jar is a particular problem.  I have to produce 
> separate EAR file when I'm deploying on Geronimo as opposed to another

> server (eg. Oracle), and commons-logging is the specific cause.  
> Actually, I think the problem is the non-J2EE compliant 
> shared-classloader scheme which seems to be the Geronimo default.  If 
> you want shared classloaders, it would make more sense to require that

> that behavior must be explicitly turned on, and it should be possible 
> to turn it on only for specific applications. (IMHO).
>
> - Ray Clough
>
>
> -----Original Message-----
> From: ammulder@gmail.com [mailto:ammulder@gmail.com] On Behalf Of 
> Aaron Mulder
> Sent: Thursday, September 14, 2006 12:30 PM
> To: user@geronimo.apache.org
> Subject: Re: Classloader Hierarchy and hidden-classes
>
> Since we have multi-parent class loaders, it may be that there's more 
> than one path to the offending server-level JAR.
>
> For example, if you want to make commons-logging hidden, and you put 
> the hidden-classes at the EAR level, but the WAR has a dependency on a

> database pool, then the WAR could find the server commons-logging 
> through either the EAR-parent path or the database-pool-parent path.
> The solution in that case would be to move the database pool 
> dependency to the EAR too, so the hidden-classes in the EAR would 
> work.  But again, there may be several such dependencies at the WAR 
> level.  Actually, if it really was commons-logging, you might not be 
> able to avoid this problem, since the WAR will automatically depend on

> either the Tomcat or Jetty module, which gives yet another route.
> Hmmm.  It's almost like we need a way to say "load only from EAR" or 
> "load only from dependency X"...
>
> Thanks,
>      Aaron
>
> On 9/13/06, Shan Karthic <sh...@gmail.com> wrote:
> > I am using geronimo 1.1.1-rc3.  I am using the release candidate 
> > instead of
> > 1.1 since 1.1.1 fixes GERONIMO-2125.
> >
> > Is there anyway I can specify, for everything under the application 
> > classloader (including child classloaders of the application 
> > classloader, such as WAR classloaders), that the classes loaded by 
> > application class loader are visible but not the ones loaded above 
> > the
>
> > application classloader?
> >
> > I want to hide some classes loaded by the server inside my 
> > application.  If I use hidden-classes I am able to hide the classes 
> > loaded by current classloader's parents.  The problem I face is if I

> > use hidden-classes at WAR level it hides the same classes loaded by 
> > EAR/application classloader as well.  If I use hidden-classes only 
> > at application level and not at WAR level, it does not hide the 
> > classes loaded by the server from the WAR class loader.  It looks 
> > like child classloaders do not know of hidden-classes specified at 
> > parent
> classloader level.  Is there any reason it is so?
> >
> > I started out trying to force my application to use its own log4j 
> > configuration accessed through commons logging.  So I had to hide 
> > org.apache.commons.logging, org.apache.log4j, 
> > org.apache.geronimo.kernel.log loaded by the server.  An utility jar

> > in the application manages references to Log objects.  The utility 
> > is
> used by EJBs and other utilities and WAR.
> >
> > I am able to get the desired behaviour by hiding the classes at both

> > app level and at WAR level with inverse-classloading at WAR level.  
> > If
>
> > I do not hide at WAR level, WAR class loader sees the classes loaded
> by the server.
> > If I hide at WAR level without inverse-classloading, WAR class 
> > loader does not see log4j classes loaded by the app class loader.  
> > But (I think so but my interpretation of the diagnostic messages 
> > from commons
>
> > logging may be wrong), due to the way Log references are stored in a

> > hierarchy of class loaders, there seems to be assignments between 
> > log4j classes loaded by app and WAR classloaders which results in
> errors.
> >
> > Now the problem is, since I have enabled inverse-classloading at WAR

> > level, classes loaded by WAR classloader do not see any 
> > config/properties files available under the EAR root.  I also think 
> > the singleton LogManager the application uses is no longer singleton

> > really as it is loaded separately by the WAR and EAR classloaders.
> >
> > As I see it, if I can hide the required classes at app classloader 
> > level, that propagates to all child classloaders without hiding the 
> > classes loaded the app classloader itself, that will help in 
> > resolving
>
> > the problem.  I searched but could not find whether there is anyway 
> > to
> do that.
> >
> > Thanks and regards,
> > Shankar.
> >
>

Re: Classloader Hierarchy and hidden-classes

Posted by Aaron Mulder <am...@alumni.princeton.edu>.
Can you define shared class loaders?  We don't share class loaders
across applications, and we don't appear to violate anything in J2EE
(at least, as far as the J2EE TCK is concerned).

What is your specific commons-logging problem?

Thanks,
     Aaron

On 9/14/06, Clough, Ray C             PWR <Ra...@pwr.utc.com> wrote:
> commons-logging.jar is a particular problem.  I have to produce separate
> EAR file when I'm deploying on Geronimo as opposed to another server
> (eg. Oracle), and commons-logging is the specific cause.  Actually, I
> think the problem is the non-J2EE compliant shared-classloader scheme
> which seems to be the Geronimo default.  If you want shared
> classloaders, it would make more sense to require that that behavior
> must be explicitly turned on, and it should be possible to turn it on
> only for specific applications. (IMHO).
>
> - Ray Clough
>
>
> -----Original Message-----
> From: ammulder@gmail.com [mailto:ammulder@gmail.com] On Behalf Of Aaron
> Mulder
> Sent: Thursday, September 14, 2006 12:30 PM
> To: user@geronimo.apache.org
> Subject: Re: Classloader Hierarchy and hidden-classes
>
> Since we have multi-parent class loaders, it may be that there's more
> than one path to the offending server-level JAR.
>
> For example, if you want to make commons-logging hidden, and you put the
> hidden-classes at the EAR level, but the WAR has a dependency on a
> database pool, then the WAR could find the server commons-logging
> through either the EAR-parent path or the database-pool-parent path.
> The solution in that case would be to move the database pool dependency
> to the EAR too, so the hidden-classes in the EAR would work.  But again,
> there may be several such dependencies at the WAR level.  Actually, if
> it really was commons-logging, you might not be able to avoid this
> problem, since the WAR will automatically depend on either the Tomcat or
> Jetty module, which gives yet another route.
> Hmmm.  It's almost like we need a way to say "load only from EAR" or
> "load only from dependency X"...
>
> Thanks,
>      Aaron
>
> On 9/13/06, Shan Karthic <sh...@gmail.com> wrote:
> > I am using geronimo 1.1.1-rc3.  I am using the release candidate
> > instead of
> > 1.1 since 1.1.1 fixes GERONIMO-2125.
> >
> > Is there anyway I can specify, for everything under the application
> > classloader (including child classloaders of the application
> > classloader, such as WAR classloaders), that the classes loaded by
> > application class loader are visible but not the ones loaded above the
>
> > application classloader?
> >
> > I want to hide some classes loaded by the server inside my
> > application.  If I use hidden-classes I am able to hide the classes
> > loaded by current classloader's parents.  The problem I face is if I
> > use hidden-classes at WAR level it hides the same classes loaded by
> > EAR/application classloader as well.  If I use hidden-classes only at
> > application level and not at WAR level, it does not hide the classes
> > loaded by the server from the WAR class loader.  It looks like child
> > classloaders do not know of hidden-classes specified at parent
> classloader level.  Is there any reason it is so?
> >
> > I started out trying to force my application to use its own log4j
> > configuration accessed through commons logging.  So I had to hide
> > org.apache.commons.logging, org.apache.log4j,
> > org.apache.geronimo.kernel.log loaded by the server.  An utility jar
> > in the application manages references to Log objects.  The utility is
> used by EJBs and other utilities and WAR.
> >
> > I am able to get the desired behaviour by hiding the classes at both
> > app level and at WAR level with inverse-classloading at WAR level.  If
>
> > I do not hide at WAR level, WAR class loader sees the classes loaded
> by the server.
> > If I hide at WAR level without inverse-classloading, WAR class loader
> > does not see log4j classes loaded by the app class loader.  But (I
> > think so but my interpretation of the diagnostic messages from commons
>
> > logging may be wrong), due to the way Log references are stored in a
> > hierarchy of class loaders, there seems to be assignments between
> > log4j classes loaded by app and WAR classloaders which results in
> errors.
> >
> > Now the problem is, since I have enabled inverse-classloading at WAR
> > level, classes loaded by WAR classloader do not see any
> > config/properties files available under the EAR root.  I also think
> > the singleton LogManager the application uses is no longer singleton
> > really as it is loaded separately by the WAR and EAR classloaders.
> >
> > As I see it, if I can hide the required classes at app classloader
> > level, that propagates to all child classloaders without hiding the
> > classes loaded the app classloader itself, that will help in resolving
>
> > the problem.  I searched but could not find whether there is anyway to
> do that.
> >
> > Thanks and regards,
> > Shankar.
> >
>

RE: Classloader Hierarchy and hidden-classes

Posted by "Clough, Ray C PWR" <Ra...@pwr.utc.com>.
commons-logging.jar is a particular problem.  I have to produce separate
EAR file when I'm deploying on Geronimo as opposed to another server
(eg. Oracle), and commons-logging is the specific cause.  Actually, I
think the problem is the non-J2EE compliant shared-classloader scheme
which seems to be the Geronimo default.  If you want shared
classloaders, it would make more sense to require that that behavior
must be explicitly turned on, and it should be possible to turn it on
only for specific applications. (IMHO).

- Ray Clough
 

-----Original Message-----
From: ammulder@gmail.com [mailto:ammulder@gmail.com] On Behalf Of Aaron
Mulder
Sent: Thursday, September 14, 2006 12:30 PM
To: user@geronimo.apache.org
Subject: Re: Classloader Hierarchy and hidden-classes

Since we have multi-parent class loaders, it may be that there's more
than one path to the offending server-level JAR.

For example, if you want to make commons-logging hidden, and you put the
hidden-classes at the EAR level, but the WAR has a dependency on a
database pool, then the WAR could find the server commons-logging
through either the EAR-parent path or the database-pool-parent path.
The solution in that case would be to move the database pool dependency
to the EAR too, so the hidden-classes in the EAR would work.  But again,
there may be several such dependencies at the WAR level.  Actually, if
it really was commons-logging, you might not be able to avoid this
problem, since the WAR will automatically depend on either the Tomcat or
Jetty module, which gives yet another route.
Hmmm.  It's almost like we need a way to say "load only from EAR" or
"load only from dependency X"...

Thanks,
     Aaron

On 9/13/06, Shan Karthic <sh...@gmail.com> wrote:
> I am using geronimo 1.1.1-rc3.  I am using the release candidate 
> instead of
> 1.1 since 1.1.1 fixes GERONIMO-2125.
>
> Is there anyway I can specify, for everything under the application 
> classloader (including child classloaders of the application 
> classloader, such as WAR classloaders), that the classes loaded by 
> application class loader are visible but not the ones loaded above the

> application classloader?
>
> I want to hide some classes loaded by the server inside my 
> application.  If I use hidden-classes I am able to hide the classes 
> loaded by current classloader's parents.  The problem I face is if I 
> use hidden-classes at WAR level it hides the same classes loaded by 
> EAR/application classloader as well.  If I use hidden-classes only at 
> application level and not at WAR level, it does not hide the classes 
> loaded by the server from the WAR class loader.  It looks like child 
> classloaders do not know of hidden-classes specified at parent
classloader level.  Is there any reason it is so?
>
> I started out trying to force my application to use its own log4j 
> configuration accessed through commons logging.  So I had to hide 
> org.apache.commons.logging, org.apache.log4j, 
> org.apache.geronimo.kernel.log loaded by the server.  An utility jar 
> in the application manages references to Log objects.  The utility is
used by EJBs and other utilities and WAR.
>
> I am able to get the desired behaviour by hiding the classes at both 
> app level and at WAR level with inverse-classloading at WAR level.  If

> I do not hide at WAR level, WAR class loader sees the classes loaded
by the server.
> If I hide at WAR level without inverse-classloading, WAR class loader 
> does not see log4j classes loaded by the app class loader.  But (I 
> think so but my interpretation of the diagnostic messages from commons

> logging may be wrong), due to the way Log references are stored in a 
> hierarchy of class loaders, there seems to be assignments between 
> log4j classes loaded by app and WAR classloaders which results in
errors.
>
> Now the problem is, since I have enabled inverse-classloading at WAR 
> level, classes loaded by WAR classloader do not see any 
> config/properties files available under the EAR root.  I also think 
> the singleton LogManager the application uses is no longer singleton 
> really as it is loaded separately by the WAR and EAR classloaders.
>
> As I see it, if I can hide the required classes at app classloader 
> level, that propagates to all child classloaders without hiding the 
> classes loaded the app classloader itself, that will help in resolving

> the problem.  I searched but could not find whether there is anyway to
do that.
>
> Thanks and regards,
> Shankar.
>

Re: Classloader Hierarchy and hidden-classes

Posted by Aaron Mulder <am...@alumni.princeton.edu>.
Since we have multi-parent class loaders, it may be that there's more
than one path to the offending server-level JAR.

For example, if you want to make commons-logging hidden, and you put
the hidden-classes at the EAR level, but the WAR has a dependency on a
database pool, then the WAR could find the server commons-logging
through either the EAR-parent path or the database-pool-parent path.
The solution in that case would be to move the database pool
dependency to the EAR too, so the hidden-classes in the EAR would
work.  But again, there may be several such dependencies at the WAR
level.  Actually, if it really was commons-logging, you might not be
able to avoid this problem, since the WAR will automatically depend on
either the Tomcat or Jetty module, which gives yet another route.
Hmmm.  It's almost like we need a way to say "load only from EAR" or
"load only from dependency X"...

Thanks,
     Aaron

On 9/13/06, Shan Karthic <sh...@gmail.com> wrote:
> I am using geronimo 1.1.1-rc3.  I am using the release candidate instead of
> 1.1 since 1.1.1 fixes GERONIMO-2125.
>
> Is there anyway I can specify, for everything under the application
> classloader (including child classloaders of the application classloader,
> such as WAR classloaders), that the classes loaded by application class
> loader are visible but not the ones loaded above the application
> classloader?
>
> I want to hide some classes loaded by the server inside my application.  If
> I use hidden-classes I am able to hide the classes loaded by current
> classloader's parents.  The problem I face is if I use hidden-classes at WAR
> level it hides the same classes loaded by EAR/application classloader as
> well.  If I use hidden-classes only at application level and not at WAR
> level, it does not hide the classes loaded by the server from the WAR class
> loader.  It looks like child classloaders do not know of hidden-classes
> specified at parent classloader level.  Is there any reason it is so?
>
> I started out trying to force my application to use its own log4j
> configuration accessed through commons logging.  So I had to hide
> org.apache.commons.logging, org.apache.log4j, org.apache.geronimo.kernel.log
> loaded by the server.  An utility jar in the application manages references
> to Log objects.  The utility is used by EJBs and other utilities and WAR.
>
> I am able to get the desired behaviour by hiding the classes at both app
> level and at WAR level with inverse-classloading at WAR level.  If I do not
> hide at WAR level, WAR class loader sees the classes loaded by the server.
> If I hide at WAR level without inverse-classloading, WAR class loader does
> not see log4j classes loaded by the app class loader.  But (I think so but
> my interpretation of the diagnostic messages from commons logging may be
> wrong), due to the way Log references are stored in a hierarchy of class
> loaders, there seems to be assignments between log4j classes loaded by app
> and WAR classloaders which results in errors.
>
> Now the problem is, since I have enabled inverse-classloading at WAR level,
> classes loaded by WAR classloader do not see any config/properties files
> available under the EAR root.  I also think the singleton LogManager the
> application uses is no longer singleton really as it is loaded separately by
> the WAR and EAR classloaders.
>
> As I see it, if I can hide the required classes at app classloader level,
> that propagates to all child classloaders without hiding the classes loaded
> the app classloader itself, that will help in resolving the problem.  I
> searched but could not find whether there is anyway to do that.
>
> Thanks and regards,
> Shankar.
>