如何配置嵌入式 Tomcat,以便类加载器能够在 CATALINA_HOME/lib 中找到类

问题描述 投票:0回答:1

我对嵌入式 Tomcat 和类加载器有疑问。

我有一个在嵌入式 Tomcat(9.0.70) 实例中运行的 java servlet 应用程序。当应用程序打包到单个 war 文件中时 – 应用程序将按预期加载并执行(类位于 WEB-INF/lib 中。

由于某些系统限制,有必要将应用程序代码与其依赖项分开交付。

我修改了应用程序 pom,将依赖项复制到 ${project.build.directory}/lib/

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>                         <outputDirectory>${project.build.directory}/lib/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

并从 war 文件中排除 jar 文件

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
             <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
    </configuration>
 </plugin> 

这将按预期构建项目 – 1 个 war 文件和 1 个 lib 目录。

创建嵌入式Tomcat环境的类包括(很多缩写):

System.setProperty("catalina.home", catHome) ;
tomcat.start();
server = tomcat.getServer();
File    base    = server.getCatalinaBase();
File    home    = server.getCatalinaHome();
log.info("starting on port:" + sslPort + 
             " with home:" + home.getAbsolutePath() + 
            " base:" + base.getAbsolutePath());

日志记录确认 CATALINA_HOME 已设置为所需的目录。

执行时收到 ClassNotFoundException

java.lang.ClassNotFoundException: com.google.gwt.user.server.rpc.RemoteServiceServlet                        
 at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1412)              
 at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1220)              
 at java.lang.ClassLoader.defineClassImpl(Native Method)                                                     
 at java.lang.ClassLoader.defineClassInternal(ClassLoader.java:396)                                          
 at java.lang.ClassLoader.defineClass(ClassLoader.java:357)                                                  
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:154)                                  
 at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2472)      
 at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:875)               
 at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1376)              
 at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1220)              
 at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:534)               
 at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:515)
 at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:149)             
 at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1067)                          
 at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1007)                                 
 at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4948)                        
 at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256)                        
 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)                                     
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)                          
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)                          
 at java.util.concurrent.FutureTask.run(FutureTask.java:277)                                                 
 at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)              
 at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)                    
 at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)                             
 at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)                               
 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)                                     
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)                          
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)                          
 at java.util.concurrent.FutureTask.run(FutureTask.java:277)                                                 
 at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)              
 at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)                    
 at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)                             
 at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265)  
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)            
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)            
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)  
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)            
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) 

我从https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html的理解是,Tomcat通用加载器将在CATALINA_HOME/lib中搜索jar。 我的 $CATALINA_HOME/lib 包含 gwt-user-2.10.0.jar,其中包含 RemoteServiceServlet.class。

我需要做什么才能从 CATALINA_HOME/lib 解决

我需要自己的类加载器吗 - 从 Tomcat 文档来看,通用加载器应该足够了(我认为)

java tomcat classloader embedded-tomcat
1个回答
0
投票

使用嵌入式 Tomcat 时,标准 Tomcat 类加载器结构不适用。您必须在类路径定义中包含所需的 jar 文件

© www.soinside.com 2019 - 2024. All rights reserved.