I want to enable the following scenario:
my web application (WAR file) is deployed on Tomcat on its own
my web application provides an API for extensions in the form of an
IFace
interface andAbstractIFace
abstract base implementation, whose class files are deployed within the WAR fileextensions to the applications are delivered as JAR files to be placed somewhere in the classpath (i.e. external to the WAR)
I compiled a ConcreteIFace
class which extends AbstractIFace
and packaged it into a JAR. I put the JAR in $TOMCAT_HOME/lib
and deployed the WAR in webapps
. When I try the following from a servlet in the WAR:
Class clazz = Class.forName("ConcreteIFace");
I get the following stack trace:
java.lang.NoClassDefFoundError: AbstractIFace
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
java.lang.ClassLoader.defineClass(ClassLoader.java:615)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
java.net.URLClassLoader.access$000(URLClassLoader.java:58)
java.net.URLClassLoader$1.run(URLClassLoader.java:197)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:190)
java.lang.ClassLoader.loadClass(ClassLoader.java:306)
java.lang.ClassLoader.loadClass(ClassLoader.java:247)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:247)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1698)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:169)
com.backbase.sample.DummyServlet.service(DummyServlet.java:14)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
A similar stack trace is presented if ConcreteIFace
directly implements IFace
instead of going through AbstractIFace
My questions are:
as all the required classes are in the application classpath, why do I have
NoClassDefFound
?is it even possible to achieve the scenario I presented at the beginning? If so, how?