LogConfigurationException: No suitable Log constructor
Displaying notes 1 - 2 of 2
August 15, 2007 18:08:34 Last update: November 08, 2007 22:00:01
I had this problem when deploying a J2EE application into Oracle app server. It worked fine with an OC4J container configured in the default group. But it failed to start with an OC4J container I created. Here's a sample stack trace of the initialization exception:
The problem was, the struts ActionServlet loads commons logging LogFactory, the log factory somehow knows that it needs log4j, but it can't load log4j since it's loaded by a different class loader. The solution for Oracle is to omit commons logging from the list of inherited libraries. Add this to
Actually, this is a quite common problem with commons-logging. If you search the web, you'll find that people have been fighting this problem for years in various environments including Tomcat, Jetty, Eclipse, Hibernate etc. Is this an inherent problem in the design of commons logging or just that people aren't using it correctly?
07/08/14 13:32:46.34 10.1.3.3.0 Started
07/08/14 13:32:51.887 springapp: Error initializing servlet
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at com.evermind.server.http.HttpApplication.loadServlet(HttpApplication.java:2313)
at com.evermind.server.http.HttpApplication.findServlet(HttpApplication.java:4824)
.
.
... lines omitted...
.
Caused by: org.apache.commons.logging.LogConfigurationException:
org.apache.commons.logging.LogConfigurationException: No suitable Log constructor
[Ljava.lang.Class;@a05e2e for org.apache.commons.logging.impl.Log4JLogger (Caused by
java.lang.NoClassDefFoundError: org/apache/log4j/Category) (Caused by
org.apache.commons.logging.LogConfigurationException: No suitable Log constructor
[Ljava.lang.Class;@a05e2e for org.apache.commons.logging.impl.Log4JLogger (Caused by
java.lang.NoClassDefFoundError: org/apache/log4j/Category))
at
org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:543)
at
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
at
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
at org.apache.struts.action.ActionServlet.<clinit>(ActionServlet.java:226)
... 22 more
The problem was, the struts ActionServlet loads commons logging LogFactory, the log factory somehow knows that it needs log4j, but it can't load log4j since it's loaded by a different class loader. The solution for Oracle is to omit commons logging from the list of inherited libraries. Add this to
META-INF/orion-application.xml solves the problem:
<imported-shared-libraries>
<remove-inherited name="apache.commons.logging"></remove-inherited>
</imported-shared-libraries>
Actually, this is a quite common problem with commons-logging. If you search the web, you'll find that people have been fighting this problem for years in various environments including Tomcat, Jetty, Eclipse, Hibernate etc. Is this an inherent problem in the design of commons logging or just that people aren't using it correctly?
2 comments 
Easy email testing with http://www.ximailstop.com
May 19, 2008 16:03:25 Last update: May 19, 2008 16:03:25
Actually this is a problem with commons logging. A detailed analysis is presented by Ceki Gülcü, the creator of log4j.
In short, the problem appears when commons logging (shorthanded as JCL following Ceki Gülcü) is loaded by a parent class loader but log4j is loaded by a child class loader. But how come JCL finds log4j in one place but fails to instantiate it following its discovery? It turned out that JCL does the discovery with one class loader (the thread context class loader) but the instantiation with a different class loader (the class loader that loaded JCL).
Therefore, the workaround is either to exclude JCL from the class loader delegation chain (as shown above for OC4J), or make log4j available to the parent class loader.
In short, the problem appears when commons logging (shorthanded as JCL following Ceki Gülcü) is loaded by a parent class loader but log4j is loaded by a child class loader. But how come JCL finds log4j in one place but fails to instantiate it following its discovery? It turned out that JCL does the discovery with one class loader (the thread context class loader) but the instantiation with a different class loader (the class loader that loaded JCL).
Therefore, the workaround is either to exclude JCL from the class loader delegation chain (as shown above for OC4J), or make log4j available to the parent class loader.
Easy email testing with http://www.ximailstop.com