portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ate Douma (JIRA)" <jetspeed-...@portals.apache.org>
Subject [jira] Created: (JS2-541) Log initialization failures when deploying on Websphere 6.0.2.x
Date Thu, 08 Jun 2006 14:19:29 GMT
Log initialization failures when deploying on Websphere 6.0.2.x

         Key: JS2-541
         URL: http://issues.apache.org/jira/browse/JS2-541
     Project: Jetspeed 2
        Type: Improvement

  Components: Components Core  
    Versions: 2.1-dev    
 Environment: Ubuntu 6.0.6, Websphere Application Server 6.0.2.x
    Reporter: Ate Douma
 Assigned to: Ate Douma 
    Priority: Blocker
     Fix For: 2.1, 2.1-dev

Websphere 6.0.2.x has a mighty annoying classloader bug which prevents the JetspeedServlet
to initialize.

When Websphere bootstraps a web application, it uses *not* the (properly) created web application
classloader (configured with PARENT_LAST)
but its own com.ibm.ws.bootstrap.ExtClassLoader (which defaults to PARENT_FIRST) for class
initializing (<clinit>) the servlet.
Note: the correct web application classloader *is* used to initialize the servlet itself (method
init(ServletConfig)), but not the static
class initialization (<clinit>).
And, starting (again) the portal through the WAS admin console, exposes a similar classloader
bug. This time, not the bootstrap.ExtClassLoader
is set as context ClassLoader but the *console* app classloader during class initialization!

We currently have two static initialized Commons Logging Log members defined in the JetspeedServlet.
Furthermore, through the jetspeed-webapp-logging component, we setup a custom Log implementation
(IsolatedLog4JLogger) which Commons Logging
picks up from the commons-logging.properties resource file (contained within the jetpeed-webapp-logging

But, WebSphere 6.0.2.x (and maybe even 6.0 but I haven't checked that one) also provides such
a commons-logging.properties resource contained within
the ws-commons-logging.jar from the globally shared lib directory.
In it, it defines: 

Note: this wasn't the case yet in WAS 5!

Now, because of the above described classloader bug (e.g. a PARENT_FIRST bootstrap classloader)
during static initialization of the JetspeedServlet, 
Commons Logging will *not* see the commons-logging.properties resource as provided by our
jetspeed-webapp-logging jar but load it from the global
  org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException:

    org.apache.commons.logging.LogConfigurationException: Class org.apache.commons.logging.impl.Jdk14Logger
does not implement Log
        at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:532)
        at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:272)
        at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:246)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:395)
        at org.apache.jetspeed.engine.JetspeedServlet.<clinit>(JetspeedServlet.java:61)
        ... 25 more

A quick workaround would be removing the Log definition from the commons-logging.properties
in ws-commons-logging.jar.
Better yet: IBM should fix this classloader bug!

But luckily (in this situation) the JetspeedServlet can be modified such that this problem
won't occurr: 
I'm going to move the initialization of the static Log instances in JetspeedServlet to the
When that method is invoked by WAS, it is done with the proper context ClassLoader and Log
initialization uses our IsolatedLog4JLogger again.

And then, after I fixed this, another classloader problem popped up!
JetspeedServlet also implements HttpSessionListener which it uses for closure of PortalStatistics
logging when a user logs out.
Now, it turns out WAS 6.0.2.x calls the Servlet.destroy() method *before* calling sessionDestroyed(HttpSessionEvent)
for existing sessions!
It seemingly does so (again) with an incorrect context classloader.
In our JetspeedServlet.sessionDestroyed() implementation we try to access the PortalStatistics
component from the SpringComponentManager.
But, as the JetspeedEngine (and thus the ComponentManager) have already shutdown because JetspeedServlet.destroy()
has already been called,
Spring is going to reload its configuration. And, as it wants to logs some info messages doing
that, its going to (re)initialize Commons Logging
again too (which also already was shutdown through the Log4JConfigurator ContextListener).
And there it is again, same exception as shown above: Jdk14Logger does not implement Log :(
So, I've also modified the JetspeedServlet.sessionDestroyed() method which will skip PortalStatistics
closure logging when the destroy() method
has been called already.

A last remark for anyone wanting to deploy a Jetspeed based portal on WAS and has dependencies
on xerces, xalan and xml-apis for its
portlet applications (just as Jetspeed itself has). 
You need to move these three jars (as well as the other already required shared libs) inside
the ear *besides* the war files, define a Class-Path
entry in each war file META-INF/MANIFEST.MF referencing these "shared" libs, and remove these
three jars from your war WEB-INF/lib folder.
This is standard shared library ear file packaging, check the J2EE docs for further information.

And finally: make sure to change the default WAS Class Loader Mode to PARENT_LAST for your
portal ear *and* each of its contained (portlet) web applications.

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:

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

View raw message