ClassNotFoundException when loading a class in Tomcat using a custom class ClassLoader

I am using Maven 3.2.3 with built-in Tomcat. Here is my configuration.

server.xml . I defined the Loader component in the context of the server.xml context element. The file location is outside the class path / 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 . UseSeparateTomcatClassLoader flag was set to 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 - custom class loader extends Tomcat by 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 was appreciated.

0
source share
2 answers

Where is your own classLoader available? You can add a project containing this class in the dependencies of the plugin:

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

OTH

Olivie

0
source

You should also define the context file AND as a plugin dependency (not just a 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 built-in tomcat (I use tomcat7-maven-plugin, version 2.2)

If you are deploying WAR in your β€œinstalled” tomcat, copy your custom classloader.jar to the tomcat lib folder.

Hope this helps!

0
source

Source: https://habr.com/ru/post/1238239/


All Articles