Re: [logging] Identify Class Loader Problems

2005-02-07 Thread Ceki Gülcü
On 2005-01-27 22:52:02, Richard Sitze wrote:
Richard,
Sorry for not responding earlier. I'be got a question regarding item C.
 C.  Host / Sub

   - commons-logging.jar#org.apache.commons.logging.Log is
 loaded/loadable by Host.

   - A host, such as JUnit, creates and manages an independent Sub
 ClassLoader

   - Sub does NOT reference Host as a parent.
How is that possible? As far as I know, a child class loader will
(by default) inherit the system class loader as a parent, in this case
'Host'.
As the set up you describe seems impossible to me, I can't make sense
of the rest of your conclusions for item 'C'. What am I missing?
   - Sub is set as the thread context ClassLoader.

   - Execution is within code belonging to Host.

   Problems:

   1. The discovery process may *fail* altogether as it starts with the
  thread context class loader, and cannot reach the Host loader.

   2. The discovery process allows a Log implementation defined by the
  Sub to be discovered by the Host, as the host executes
  Host[LogFactory], via the thread context class loader.
  Consider the case where the *Sub* defines
  commons-logging.properties
  or META-INF/Services/org.apache.commons.logging.Log.

--
Ceki Gülcü
  The complete log4j manual: http://www.qos.ch/log4j/

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: [logging] Identify Class Loader Problems

2005-02-07 Thread robert burrell donkin
On Mon, 2005-02-07 at 17:17, Ceki Gülcü wrote:
 On 2005-01-27 22:52:02, Richard Sitze wrote:
 
 Richard,
 
 Sorry for not responding earlier. I'be got a question regarding item C.
 
   C.  Host / Sub
  
 - commons-logging.jar#org.apache.commons.logging.Log is
   loaded/loadable by Host.
  
 - A host, such as JUnit, creates and manages an independent Sub
   ClassLoader
  
 - Sub does NOT reference Host as a parent.
 
 How is that possible? As far as I know, a child class loader will
 (by default) inherit the system class loader as a parent, in this case
 'Host'.

i believe richard is talking about the case where both the host and the
sub inherit (directly or indirectly) from the system classloader but
where the sub does not inherit from the host. 

 As the set up you describe seems impossible to me, I can't make sense
 of the rest of your conclusions for item 'C'. What am I missing?

i believe that this arrangement happens in some EJB containers and is
also used by some tools (for example, byte code enhancers).

- robert


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [logging] Identify Class Loader Problems

2005-02-07 Thread Richard Sitze
Oh for better diagramming facilities in mail :-)

***
Richard A. Sitze
IBM WebSphere WebServices Development

Ceki Gülcü [EMAIL PROTECTED] wrote on 02/07/2005 11:17:36 AM:

 
 On 2005-01-27 22:52:02, Richard Sitze wrote:
 
 Richard,
 
 Sorry for not responding earlier. I'be got a question regarding item C.
 
   C.  Host / Sub
  
 - commons-logging.jar#org.apache.commons.logging.Log is
   loaded/loadable by Host.
  
 - A host, such as JUnit, creates and manages an independent Sub
   ClassLoader
  
 - Sub does NOT reference Host as a parent.
 
 How is that possible? As far as I know, a child class loader will
 (by default) inherit the system class loader as a parent, in this case
 'Host'.


   System ClassLoader
|
 +--+-+
 ||
Host --- creates -- Sub


 As the set up you describe seems impossible to me, I can't make sense
 of the rest of your conclusions for item 'C'. What am I missing?
 
 - Sub is set as the thread context ClassLoader.
  
 - Execution is within code belonging to Host.
  
 Problems:
  
 1. The discovery process may *fail* altogether as it starts with 
the
thread context class loader, and cannot reach the Host loader.
  
 2. The discovery process allows a Log implementation defined by the
Sub to be discovered by the Host, as the host executes
Host[LogFactory], via the thread context class loader.
Consider the case where the *Sub* defines
commons-logging.properties
or META-INF/Services/org.apache.commons.logging.Log.
 
 
 
 
 -- 
 Ceki Gülcü
 
The complete log4j manual: http://www.qos.ch/log4j/
 
 
 
 -
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 


Re: [logging] Identify Class Loader Problems

2005-02-06 Thread robert burrell donkin
On Fri, 2005-01-28 at 20:15, Richard Sitze wrote:

hi richard

(apologies for the delay: machine problems) 

 I'd like to begin to identify the ClassLoader problems with the
 current JCL discovery mechanism.  If you are aware of additional
 issues, please respond and let's get them all out on the table.

setting aside bugs and environments where discovery is not going to work
(for example, untrusted applets), i think your analysis has captured
everything.

 I believe the following two scenarios summarize the specific issues,
 as well as more general problems.
 
 A.  Parent / Child ClassLoaders, General

snip

 B.  Parent / Child ClassLoaders, Child does not defer to Parent first.

snip

 C.  Host / Sub

snip

 SUMMARY of PROBLEM:
 
 There are ONE general problem at work here:
   - Disrespect for proper ISOLATION as defined by ClassLoaders
 
 The fundamental problem is dealing with the thread context classloader
 in [common] situations where it represents an isolated or
 isolating mechanism.  For scenario A, we are simply loading
 when we should be.  For scenario B, by setting child first
 search behavior, we are granting the child a degree of independence.
 For scenario C, by creating a Sub that isn't related to the
 parent at all.
 
 In both cases, JCL behavior incorrectly *assumes* that a more
 traditional Parent/Child relationship exists with the thread context
 classloader.
 
 While the current mechanism *is* generally useful, I'm realizing
 that we've only addressed one corner case, and have broken other
 *very* reasonable classloader configurations.

+1

 WHAT CAN BE DONE:
 
 - For A.1, For auto configuration of for predefined wrapper impls,
   any impl class should be located using the ClassLoader of the
   wrapper, never the thread context class loader.

+1

 Detect independent thread context class loaders and respect the
 boundries.  By independent, I mean any classloader that gives
 preference to it's own internal classes.
 
 - The trivial case is a thread context class loader that doesn't
   include the current ClassLoader [used to load 'this' class, i.e.
   LogFactory] in it's hierarchy.  In this case, the discovery
   mechanism simply has *NO* business crossing the boundry, it should
   revert back to using the ClassLoader used to load the [currently
   executing] LogFactory.  This should cover scenario C.
 
 - Scenario B is a bit more difficult to resolve.
 
   For B.1, the child resource manager [LogFactory] is in
   control.  We can presume during discovery that we should NOT
   look any higher up the hierarchy than the level at which our
   interface [Log or LogFactory] was discovered for configuration
   or implementation resources.  [various games can be played
   to determine which loader in a hierarchy was used to obtain
   any particular resource].
 
   For B.2, the parent resouce manager [LogFactory] is in
   control.  We can check by requesting our base interface [Log or
   LogFactory] from the thread context class loader.  If the class
   returned is not the same as what we have in the Parent, then
   we should treat this as the trivial case: use the LogFactory
   classloader and do not cross that boundry.

i think that this last paragraph is the key: the acid test for
compatibility is whether the Log class loaded by the context class
loader is the same as the Log class loaded by the LogFactory loader.
when this test fails, it is appropriate to use the classloader used to
load LogFactory.

i can't think of any use cases which work now which would be broken by
changing the code to respect the classloader boundaries in this fashion.
can anyone else?

- robert


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [logging] Identify Class Loader Problems

2005-02-01 Thread Ceki Gülcü
On 2005-01-27 22:52:02, Richard Sitze wrote:
 A.  Parent / Child ClassLoaders, General

   - commons-logging.jar#org.apache.commons.logging.Log is
 loaded/loadable by Parent.

   - Child is the thread context ClassLoader.

   - Parent defines a LogAWrapper for LogAImpl

   - Child defines a LogAImpl

   Problem:

   1. Discovery finds Child[LogAImpl], and attempts to instantiate
  LogAWrapper in Parent.  Fails, because Parent cannot see child.
Richard,
Forgive my nitpicking, but what do you mean exactly by LogAWrapper? By
LogAImpl?
Many thanks in advance for your response.
--
Ceki Gülcü
  The complete log4j manual: http://www.qos.ch/log4j/

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: [logging] Identify Class Loader Problems

2005-02-01 Thread Richard Sitze
Ceki Gülcü [EMAIL PROTECTED] wrote on 02/01/2005 01:55:13 PM:

 
 On 2005-01-27 22:52:02, Richard Sitze wrote:
 
   A.  Parent / Child ClassLoaders, General
  
 - commons-logging.jar#org.apache.commons.logging.Log is
   loaded/loadable by Parent.
  
 - Child is the thread context ClassLoader.
  
 - Parent defines a LogAWrapper for LogAImpl
  
 - Child defines a LogAImpl
  
 Problem:
  
 1. Discovery finds Child[LogAImpl], and attempts to instantiate
LogAWrapper in Parent.  Fails, because Parent cannot see child.
 
 Richard,
 
 Forgive my nitpicking, but what do you mean exactly by LogAWrapper? By
 LogAImpl?

By wrapper, I mean a commons-logging wrapper class.
by impl, I mean a target logger implementation, such as Log4J.

This is, I believe, the Log4J problem you've previously described.  Where 
you drop Log4J in the client, and it caused the discovery mechanism to 
throw an exception.

LogA is any logger... such as Log4J:

 Discovery finds Child[Log4J], and attempts to instantiate
 Log4JLogger in Parent.  Fails, because Parent cannot see child:
 org.apache.commons.logging.impl.Log4JLogger [in parent] cannot load
 org.apache.log4j.Logger [in child].

 
 Many thanks in advance for your response.
 
 
 -- 
 Ceki Gülcü
 
The complete log4j manual: http://www.qos.ch/log4j/
 

***
Richard A. Sitze
IBM WebSphere WebServices Development


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



[logging] Identify Class Loader Problems

2005-01-28 Thread Richard Sitze
[re-send.. I don't see this picked up... hmmm]

I'd like to begin to identify the ClassLoader problems with the
current JCL discovery mechanism.  If you are aware of additional
issues, please respond and let's get them all out on the table.

I believe the following two scenarios summarize the specific issues,
as well as more general problems.

A.  Parent / Child ClassLoaders, General

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Parent.

  - Child is the thread context ClassLoader.

  - Parent defines a LogAWrapper for LogAImpl

  - Child defines a LogAImpl

  Problem:

  1. Discovery finds Child[LogAImpl], and attempts to instantiate
 LogAWrapper in Parent.  Fails, because Parent cannot see child. 


B.  Parent / Child ClassLoaders, Child does not defer to Parent first.

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Parent.

  - Child is the thread context ClassLoader.

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded by the Child.

  - It is clear that Parent[Log] and Child[Log] are different Classes.

  Problems:

  1. The discovery process allows a Log implementation defined by the
 Parent to be discovered by the Child as the child executes
 Child[LogFactory].  This does NOT happen by way of the
 relationship between the Log and the LogImpl, because the
 Parent[Log] and the Child[Log] are not the same class.
 It happens via classes named in configuration files:
 commons-logging.properties and
 META-INF/Services/org.apache.commons.logging.Log.

  2. The discovery process allows a Log implementation defined by the
 Child to be discovered by the Parent, as the parent executes
 Parent[LogFactory], via the thread context class loader.

 Examples include dropping Log4J into the child, and the [old]
 behavior that favors Log4J forcing it and it's JCL wrapper
 to be loaded via the Child and exposed to the parent.


C.  Host / Sub

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Host.

  - A host, such as JUnit, creates and manages an independent Sub
ClassLoader

  - Sub does NOT reference Host as a parent.

  - Sub is set as the thread context ClassLoader.

  - Execution is within code belonging to Host.

  Problems:

  1. The discovery process may *fail* altogether as it starts with the
 thread context class loader, and cannot reach the Host loader.

  2. The discovery process allows a Log implementation defined by the
 Sub to be discovered by the Host, as the host executes
 Host[LogFactory], via the thread context class loader.
 Consider the case where the *Sub* defines
 commons-logging.properties
 or META-INF/Services/org.apache.commons.logging.Log.


SUMMARY of PROBLEM:

There are ONE general problem at work here:
  - Disrespect for proper ISOLATION as defined by ClassLoaders

The fundamental problem is dealing with the thread context classloader
in [common] situations where it represents an isolated or
isolating mechanism.  For scenario A, we are simply loading
when we should be.  For scenario B, by setting child first
search behavior, we are granting the child a degree of independence.
For scenario C, by creating a Sub that isn't related to the
parent at all.

In both cases, JCL behavior incorrectly *assumes* that a more
traditional Parent/Child relationship exists with the thread context
classloader.

While the current mechanism *is* generally useful, I'm realizing
that we've only addressed one corner case, and have broken other
*very* reasonable classloader configurations.


WHAT CAN BE DONE:

- For A.1, For auto configuration of for predefined wrapper impls,
  any impl class should be located using the ClassLoader of the
  wrapper, never the thread context class loader.


Detect independent thread context class loaders and respect the
boundries.  By independent, I mean any classloader that gives
preference to it's own internal classes.

- The trivial case is a thread context class loader that doesn't
  include the current ClassLoader [used to load 'this' class, i.e.
  LogFactory] in it's hierarchy.  In this case, the discovery
  mechanism simply has *NO* business crossing the boundry, it should
  revert back to using the ClassLoader used to load the [currently
  executing] LogFactory.  This should cover scenario C.

- Scenario B is a bit more difficult to resolve.

  For B.1, the child resource manager [LogFactory] is in
  control.  We can presume during discovery that we should NOT
  look any higher up the hierarchy than the level at which our
  interface [Log or LogFactory] was discovered for configuration
  or implementation resources.  [various games can be played
  to determine which loader in a hierarchy was used to obtain
  any particular resource].

  For B.2, the parent resouce manager [LogFactory] is in
  control.  We can check by requesting our base interface [Log or
  LogFactory] from the 

[logging] Identify Class Loader Problems

2005-01-27 Thread Richard Sitze
I'd like to begin to identify the ClassLoader problems with the
current JCL discovery mechanism.  If you are aware of additional
issues, please respond and let's get them all out on the table.

I believe the following two scenarios summarize the specific issues,
as well as more general problems.

A.  Parent / Child ClassLoaders, General

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Parent.

  - Child is the thread context ClassLoader.

  - Parent defines a LogAWrapper for LogAImpl

  - Child defines a LogAImpl

  Problem:

  1. Discovery finds Child[LogAImpl], and attempts to instantiate
 LogAWrapper in Parent.  Fails, because Parent cannot see child. 


B.  Parent / Child ClassLoaders, Child does not defer to Parent first.

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Parent.

  - Child is the thread context ClassLoader.

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded by the Child.

  - It is clear that Parent[Log] and Child[Log] are different Classes.

  Problems:

  1. The discovery process allows a Log implementation defined by the
 Parent to be discovered by the Child as the child executes
 Child[LogFactory].  This does NOT happen by way of the
 relationship between the Log and the LogImpl, because the
 Parent[Log] and the Child[Log] are not the same class.
 It happens via classes named in configuration files:
 commons-logging.properties and
 META-INF/Services/org.apache.commons.logging.Log.

  2. The discovery process allows a Log implementation defined by the
 Child to be discovered by the Parent, as the parent executes
 Parent[LogFactory], via the thread context class loader.

 Examples include dropping Log4J into the child, and the [old]
 behavior that favors Log4J forcing it and it's JCL wrapper
 to be loaded via the Child and exposed to the parent.


C.  Host / Sub

  - commons-logging.jar#org.apache.commons.logging.Log is
loaded/loadable by Host.

  - A host, such as JUnit, creates and manages an independent Sub
ClassLoader

  - Sub does NOT reference Host as a parent.

  - Sub is set as the thread context ClassLoader.

  - Execution is within code belonging to Host.

  Problems:

  1. The discovery process may *fail* altogether as it starts with the
 thread context class loader, and cannot reach the Host loader.

  2. The discovery process allows a Log implementation defined by the
 Sub to be discovered by the Host, as the host executes
 Host[LogFactory], via the thread context class loader.
 Consider the case where the *Sub* defines
 commons-logging.properties
 or META-INF/Services/org.apache.commons.logging.Log.


SUMMARY of PROBLEM:

There are ONE general problem at work here:
  - Disrespect for proper ISOLATION as defined by ClassLoaders

The fundamental problem is dealing with the thread context classloader
in [common] situations where it represents an isolated or
isolating mechanism.  For scenario A, we are simply loading
when we should be.  For scenario B, by setting child first
search behavior, we are granting the child a degree of independence.
For scenario C, by creating a Sub that isn't related to the
parent at all.

In both cases, JCL behavior incorrectly *assumes* that a more
traditional Parent/Child relationship exists with the thread context
classloader.

While the current mechanism *is* generally useful, I'm realizing
that we've only addressed one corner case, and have broken other
*very* reasonable classloader configurations.


WHAT CAN BE DONE:

- For A.1, For auto configuration of for predefined wrapper impls,
  any impl class should be located using the ClassLoader of the
  wrapper, never the thread context class loader.


Detect independent thread context class loaders and respect the
boundries.  By independent, I mean any classloader that gives
preference to it's own internal classes.

- The trivial case is a thread context class loader that doesn't
  include the current ClassLoader [used to load 'this' class, i.e.
  LogFactory] in it's hierarchy.  In this case, the discovery
  mechanism simply has *NO* business crossing the boundry, it should
  revert back to using the ClassLoader used to load the [currently
  executing] LogFactory.  This should cover scenario C.

- Scenario B is a bit more difficult to resolve.

  For B.1, the child resource manager [LogFactory] is in
  control.  We can presume during discovery that we should NOT
  look any higher up the hierarchy than the level at which our
  interface [Log or LogFactory] was discovered for configuration
  or implementation resources.  [various games can be played
  to determine which loader in a hierarchy was used to obtain
  any particular resource].

  For B.2, the parent resouce manager [LogFactory] is in
  control.  We can check by requesting our base interface [Log or
  LogFactory] from the thread context class loader.  If the class