Instance doesn't start | log4j.jar file in the WebLogic APP-INF/lib

Issue

You are running your instances in WebLogic and you have log4j.jar under APP-INF/lib. When you try to start your publish instance (or the second instance on the same appserver), you get an error similar to:
javax.servlet.ServletException
	at weblogic.servlet.internal.ServletStubImpl.createServlet(ServletStubImpl.java:909)
	at weblogic.servlet.internal.ServletStubImpl.createInstances(ServletStubImpl.java:873)
	at weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:812)
	at weblogic.servlet.internal.WebAppServletContext.preloadServlet(WebAppServletContext.java:3281)
	at weblogic.servlet.internal.WebAppServletContext.preloadServlets(WebAppServletContext.java:3226)
	at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:3207)
	at weblogic.servlet.internal.WebAppServletContext.setStarted(WebAppServletContext.java:5737)

Solution

Do one of the following:

  • Don't put the log4j.jar in the common/shared classloader. It is a bad idea to have a shared log4j for all webapp, since they do not use their own categories. For example, you can't tell from which webapp the log message originates.
  • Move the following jars to the common classloader:
    • crx-commons.jar
    • crx-api.jar
    • jcr.jar
    • commons-logging.jar
    • commons-collections.jar
    • xercesImpl.jar

Additional information

log4j is global for all classes in the same classloader. A class in author webapp registers the FmtLogger (in crx-commons.jar) as logger in the 'global' log4j category. Then, the publish class tries to acquire the same logger. There is a class cast exception, because it has another version of the FmtLogger in its classpath.