2015-07-28 1 views
0

J'utilise Maven 3.2.3 avec un Tomcat intégré. Voici ma configuration.ClassNotFoundException lors du chargement de la classe dans Tomcat à l'aide de ClassLoader personnalisé

server.xml - J'ai défini le composant Loader dans l'élément de contexte de server.xml. L'emplacement du fichier est en dehors du classpath sous /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 - Le useSeparateTomcatClassLoader drapeau a été fixé dans la 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> 

mise en œuvre de ClassLoader est ajouté en tant que dépendance

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

myClassLoader - le chargeur de classe personnalisée étend par défaut de 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); 
} 
} 

Exception lancée par 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) 

Toute aide appréciée.

Répondre

0

Où votre propre classLoader est-il disponible? Vous pouvez ajouter le projet contenant cette classe dans les dépendances de plugin:

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

OTH

Olivier

+0

Merci d'avoir répondu. Il semble que je ne comprenne pas le concept de comment et où Tomcat cherche mon ClassLoader personnalisé. Pourquoi est-il nécessaire d'ajouter cette classe en tant que dépendance jar? Ne peut-il pas simplement résider dans le classpath, où le WebappClassLoader délègue tout le mécanisme de chargement de classe à mon propre chargeur? S'il te plaît, éclaire-moi. – user46726

+0

Non, car il y a 2 classloaders: conteneur Tomcat et votre application. Le chemin de classe de l'application calculé à partir de projet/dépendances est donc pour votre application. Tomcat a donc besoin de votre classloader qui n'est pas disponible. –

+0

Désolé pour la réponse tardive. La dépendance a été ajoutée dans le pom (post édité), mais je reçois toujours l'erreur. Toutes les idées pourquoi? – user46726

0

Vous devez définir également le fichier contexte et en tant que dépendance du plug-in et (non juste la dépendance du projet).

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

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

Cela devrait fonctionner pour le tomcat embarqué (j'utilise tomcat7-maven-plugin, version 2.2)

Si vous déployez le fichier WAR dans un tomcat "installé", copiez le classloader.jar personnalisé dans le dossier lib de tomcat.

Espérons que cela aide!