ClassNotFoundException while loading class in Tomcat using custom ClassLoader

邮差的信 提交于 2019-12-25 16:26:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!