2015-07-28 4 views
0

Я использую Maven 3.2.3 со встроенным Tomcat. Вот моя конфигурация.ClassNotFoundException при загрузке класса в Tomcat с использованием пользовательского класса ClassLoader

server.xml - Я определил компонент Loader в контексте контекстного элемента server.xml. Расположение файла находится вне пути к классам при /CONF/котом

.... 
<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 флаг был установлен в ПОМ добавляется

<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 в качестве зависимости

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

MyClassLoader - пользовательский класс загрузчик распространяется по умолчанию для Tomcat 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); 
} 
} 

Исключения брошенного 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) 

Любой помощь приветствуется.

ответ

0

Где ваш собственный загрузчик классов? Вы можете добавить проект, содержащий этот класс в зависимости плагин:

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

OTH

Оливье

+0

Спасибо, что ответили. Похоже, я не понимаю концепцию того, как и где tomcat ищет свой пользовательский ClassLoader. Почему необходимо добавлять этот класс в зависимость от jar? Не может ли он просто находиться в пути к классам, где WebappClassLoader делегирует весь механизм загрузки класса моему собственному загрузчику? Пожалуйста, просветите меня. – user46726

+0

Нет, потому что есть 2 загрузчика классов: контейнер Tomcat и ваше приложение. Таким образом, путь класса приложения, рассчитанный из проекта/зависимостей, предназначен для вашего приложения. Поэтому Tomcat нужен ваш загрузчик классов, который недоступен. –

+0

Извините за поздний ответ. Зависимость была добавлена ​​в pom (отредактированный пост), но я все еще получаю ошибку. Почему? – user46726

0

Вы должны также определить файл контекста и как зависимость плагина, а также (не просто зависимость от проекта).

Пример 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> 

Это должно работать для встроенного котом (я использую tomcat7-Maven-плагин, версия 2.2)

Если вы развертываете WAR в «установленный» tomcat, скопируйте свой пользовательский classloader.jar в папку tomcat lib.

Надеюсь, это поможет!