使用自定义ClassLoader在Tomcat中加载类时出现ClassNotFoundException

时间:2015-07-28 21:08:59

标签: maven classloader tomcat6 maven-tomcat-plugin

我使用Maven 3.2.3和嵌入式Tomcat。这是我的配置。

server.xml - 我已经在server.xml的Context Element中定义了Loader组件。该文件的位置在 / conf / tomcat

下的类路径之外
zoomFactor

pom.xml - 在pom中设置 useSeparateTomcatClassLoader 标志

....
<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>
....   

将ClassLoader实现添加为依赖项

<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>

MyClassLoader - 自定义类加载器扩展了Tomcat的默认 WebappClassLoader

<dependency>
        <groupId>com.sample</groupId>
        <artifactId>customclassloader</artifactId>
        <version>1.0.0-SNAPSHOT</version>
</dependency>

Tomcat引发的异常

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);
}
}

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:0)

您自己的classLoader可用吗? 您可以在插件依赖项中添加包含此类的项目:

<plugin>
  <dependencies>
  ........ here ......
  </dependencies>
</plugin>

OTH

奥利弗

答案 1 :(得分:0)

您还必须将上下文文件AND定义为插件的依赖项(而不仅仅是项目依赖项)。

示例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>

示例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>

这适用于嵌入式tomcat(我使用tomcat7-maven-plugin,2.2版)

如果要将WAR部署到“已安装”的tomcat中,请将自定义classloader.jar复制到tomcat lib文件夹中。

希望这有帮助!