commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ate Douma <...@douma.nu>
Subject Re: Fwd: commons-logging unsuited for cross-context webapplication invocation usage - migrating to slf4j?
Date Fri, 24 Apr 2009 00:09:33 GMT
Hi all,

Thanks to Dennis for bringing this to my attention :)

Sorry for chiming in so late but I wasn't subscribed to the list and unaware of the discussion
going on about our migration to slf4j at 
Pluto, Jetspeed-2, and in time probably all our Apache Portals projects.

I just read through the whole of this thread and noticed a lot of speculation and misinterpretation
of the real reason why we choose to 
migrate away from CL.

Let me first try to describe in a nutshell what IMO is the core of our problem with CL.

Consider class A and B, where A has a usage/reference to class B.
Class B has a statically defined CL Log, e.g. like: private static final Log log = LogFactory.getLog(B.class);

Class A is being invoked, such that class B is pulled into usage for the first time.
The ClassLoader of class A will be used to load class B, and because of the static Log definition,
the same ClassLoader will be used for 
accessing and invoking LogFactory.getLog().
Then, LogFactory will determine the actual logger implementation using the current ContextClassLoader.
If *within* that ContextClassLoader a 
commons-logging.properties resource is defined, it will use it to lookup the implementation
class and then load that class also using the 
ContextClassLoader.

The common use-case here is that the ContextClassLoader and the Classloader of class A/B are
actually the same, so everything goes as 
expected and the loaded logging configuration will match the intended usage of the developer
defining it.

However, if the ContextClassLoader is *not* the same as the ClassLoader of class A/B, this
all breaks down terribly.

To make this concrete, I'll describe the actually issue as I encountered it with Pluto (albeit
a little bit simplified/abbreviated).

The portletcontainer (jar), which resides within the WEB-INF/lib of the Pluto web application,
contains the classes PortletRequest (A) and 
PortletPreferences (B), with PortletPreferences defining a private static Log log = LogFactory.getLog(PortletPreferences.class).
A different web application, e.g. a portlet application "test" also uses CL, and provides
a class TestPortlet within its own WEB-INF/classes.

When Pluto needs to "aggregate" the content of this TestPortlet, it invokes it render(PortletRequest,
PortletResponse) method using a 
"cross-context" call from the Pluto web application to the "test" web application.
The TestPortlet.render method receives the PortletRequest object (as loaded from the Pluto
WEB-INF/lib) and invokes its 
PortletRequest.getPortletPreferences() method. If the PortletPreferences class hasn't been
accessed yet before, this will cause the 
ClassLoader of PortletRequest, being the Pluto webapp ClassLoader, to now load the PortletPreferences
class.
But, because the current ContextClassLoader is the "test" webapp ClassLoader, LogFactory will
lookup the logger implementation from the 
"test" webapp...
With as result that logging output for the PortletPreferences class will end up in the target
as specified by the "test" webapp, not in the 
one (as expected) as configured for the Pluto webapp.

As should hopefully be clear from the above, this problem really has *nothing* to do with
the Portlet spec in itself, or how Pluto is 
implementing it.

IMO, the "natural" and expected result of a static initialization like a Log definition is
that its configuration and behavior is tied to 
the class defining it, for which it should (by default) use the same ClassLoader.

Any application using multiple ClassLoaders can be "hit" by this same issue, and although
portals *by nature* rely heavily upon 
"cross-context" web/portlet application interaction (which actually is described in the portlet
spec), that is not limited to portals only.
Although not a formal servlet spec feature, all Java web servers support cross-context web
application invocation nowadays and already long 
before the portlet spec was defined. And it is used for far more purposes than portals only.

The only possible workaround I could come up with was extending LogFactory itself and temporarily
switching/enforcing the current 
ContextClassLoader to that of the class itself, but obviously we didn't even consider that
as a real option.

I hope the above now better explains why we had to migrate away from CL.
If not, I'll be happy to further elaborate on this of course.

With kind regards,

Ate


Ralph Goers wrote:
> FWIW - I subscribe to this list so I saw the message but have not 
> participated in the discussion.
> 
> This just adds to my concern with respect to what to do with commons 
> logging.
> 
> Ralph
> 
> Begin forwarded message:
> 
>> From: Eric Dalquist <eric.dalquist@doit.wisc.edu>
>> Date: April 20, 2009 1:47:42 PM PDT
>> To: pluto-dev@portals.apache.org
>> Subject: Re: commons-logging unsuited for cross-context webapplication 
>> invocation usage - migrating to slf4j?
>> Reply-To: pluto-dev@portals.apache.org
>> Reply-To: pluto-dev@portals.apache.org
>>
>> +1 to SLF4J several Jasig projects are also looking at it as an 
>> alternative to JCL.
>>
>> -Eric
>>
>> Ate Douma wrote:
>>> Pluto community,
>>>
>>> I'd like to ask your intention for issue PLUTO-553:
>>>
>>>  http://issues.apache.org/jira/browse/PLUTO-553
>>>
>>> Detailed information about this blocking issue can be found at above 
>>> JIRA page.
>>> As I have described there, if nobody objects I intend to commit the 
>>> migration to sfl4j soon.
>>> Any comments/feedback of further discussion is of course welcome.
>>>
>>> Regards,
>>>
>>> Ate
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message