问题
I'm using Maven 3.2.3 with an embedded Tomcat. Here is my configuration.
server.xml - I've defined the Loader Component within the server.xml's Context Element. The location of the file is outside the classpath under /conf/tomcat
....
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
<Context docBase="../../myapp/" path="/myapp">
<Loader loaderClass="com.sample.MyClassLoader" delegate="false" useSystemClassLoaderAsParent="false" reloadable="true"/>
</Context>
</Host>
....
pom.xml - The useSeparateTomcatClassLoader flag was set in the pom
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<path>/</path>
<serverXml>${basedir}/conf/tomcat/server.xml</serverXml>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
<contextReloadable>true</contextReloadable>
</configuration>
</plugin>
ClassLoader implementation is added as a dependency
<dependency>
<groupId>com.sample</groupId>
<artifactId>customclassloader</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
MyClassLoader - the custom class loader extends Tomcat's default WebappClassLoader
public class MyClassLoader extends org.apache.catalina.loader.WebappClassLoader {
private final Set<String> customClassesToLoad = new HashSet<String>(Arrays.asList("com.sample.CustomClassToLoad"));
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return isCustomClassesToLoad(name)? loadCustomClass(name): super.loadClass(name);
}
private Class<?> loadCustomClass(String name) {
/* return custom class*/
}
private boolean isCustomClassesToLoad(String name) {
return customClassesToLoad.contains(name);
}
}
Exception thrown by Tomcat
INFO: The APR based Apache Tomcat Native library which allows optimal
performance in production environments was not found on the
java.library.path: C:\Program Files\Java\jdk1.6.0_45\bin;
28.07.2015 22:33:08 org.apache.tomcat.util.digester.SetPropertiesRule
begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context/Loader}
Setting property 'useSystemClassLoaderAsParent' to 'false' did not find
a matching property.
28.07.2015 22:33:08 org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
28.07.2015 22:33:08 org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 319 ms
28.07.2015 22:33:08 org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
28.07.2015 22:33:08 org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.29
28.07.2015 22:33:08 org.apache.catalina.loader.WebappLoader start
SCHWERWIEGEND: LifecycleException
java.lang.ClassNotFoundException:
com.sample.MyClassLoader
at
org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:259)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:242)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:227)
Any help appreciated.
回答1:
Where your own classLoader is available? You can add the project containing this class in the plugin dependencies:
<plugin>
<dependencies>
........ here ......
</dependencies>
</plugin>
OTH
Olivier
回答2:
You have to also define the context file AND as a dependency of the plugin as well (not just project dependency).
Example pom.xml:
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<path>/</path>
<serverXml>${basedir}/conf/tomcat/server.xml</serverXml>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
<contextReloadable>true</contextReloadable>
<contextFile>${project.basedir}/src/main/webapp/WEB-INF/context.xml</contextFile>
</configuration>
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>customclassloader</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</build>
....
....
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>customclassloader</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
Example context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/YourWebApplicationContext">
<Loader delegate="true" loaderClass="com.sample.customclassloader.MyClassLoader" searchExternalFirst="true"/>
</Context>
This should work for the embedded tomcat (I use tomcat7-maven-plugin, version 2.2)
If you are deploying the WAR into a "installed" tomcat, copy you custom classloader.jar into the tomcat lib folder.
Hope this helps!
来源:https://stackoverflow.com/questions/31687130/classnotfoundexception-while-loading-class-in-tomcat-using-custom-classloader