I have a Spring-based app (packaged into a WAR) that runs fine in Jetty and "ordinary" Tomcat 7, but produces strange NoClassDefFoundError when it's deployed into tc Server with Spring Insight. The class that it's complaining can't be found is definitely in a JAR in the WEB-INF/lib
folder (and I've double-checked that no competing JARs exist in the Tomcat shared lib folder).
Here's the stack trace, showing that Spring thinks it can't locate the class HierarchicalLoop
:
java.lang.ClassNotFoundException: com.foo.HierarchicalLoop<com.foo.Loop>
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714) ~[na:na]
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) ~[na:na]
... 32 common frames omitted
Wrapped by: java.lang.NoClassDefFoundError: com/foo/HierarchicalLoop<com/foo/Loop>
at java.lang.Class.getDeclaredConstructors0(Native Method) ~[na:1.7.0_60]
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2532) ~[na:1.7.0_60]
at java.lang.Class.getConstructor0(Class.java:2842) ~[na:1.7.0_60]
at java.lang.Class.getDeclaredConstructor(Class.java:2053) ~[na:1.7.0_60]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1094) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 26 common frames omitted
Wrapped by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'x12Builder' defined in class path resource [spring/x12-builder-config.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: com/foo/HierarchicalLoop<com/foo/X12Loop>
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1101) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
If I disable Insight in the server instance, the app loads fine, and this is reproducible on 3 different machines. As I said, the WAR also loads correctly under Jetty and Tomcat (without Insight). So I'm pretty sure it's narrowed down to something that Insight does.
In my experience, these kinds of mysterious NoClassDefFoundError
or ClassNotFoundException
errors are often caused by class loader mixups. For example, the container's root classloader trying to load classes from an application JAR. But in this case Insight is a black box to me, I'm not sure what it's doing under the covers. I suspect that maybe the Spring classes are coming from a classloader other than my application's classloader, which would explain why Spring can't see the classes from JARs in the application's lib
. But that's little more than educated speculation, and even if it were accurate I have no idea how to resolve it.
Any ideas for troubleshooting or insight into how Insight works are appreciated.
It turns out that this was due to some kind of limitation or bug in Insight. The class that it was complaining about, HierarchicalLoop<Loop>
was causing problems with the Insight classloader (TomcatWeavingInsightClassLoader
) which made it report it as a ClassNotFoundException
. It has something to do with type parameters; here's the two classes that were involved in causing the class loader problems:
public class Loop<ChildType extends Loop> {
//...
}
public class HierarchicalLoop<ChildType extends Loop> extends Loop<ChildType> {
//...
}
This is perfectly valid Java and no other containers/classloaders (Tomcat, Jetty, JUnit) have any problem loading those classes. But Insight does, for some reason.
There are subclasses of HierarchicalLoop
but all of them just specify Loop
as the ChildType
parameter, so the parameter isn't actually needed. So I was able to work around the problem by removing the type parameter from HierarchicalLoop
:
public class HierarchicalLoop extends Loop<Loop> {
//..
}
I'm pretty sure this is a bug in Insight; I'd like to report it but have been unable to find any community support or bug reporting channel.