Spring Tomcat7 和 Log4 上的引导部署问题

Spring Boot Deployment on Tomcat7 and Log4 issue

我正在尝试 运行 我的 spring 独立启动应用程序 tomcat。但是它给了我这个错误

java.io.IOException: java.lang.ClassNotFoundException: org.apache.logging.log4j.core.web.Log4jServletContainerInitializer
        at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:200)
        at org.apache.catalina.startup.WebappServiceLoader.load(WebappServiceLoader.java:158)
        at org.apache.catalina.startup.ContextConfig.processServletContainerInitializers(ContextConfig.java:1579)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1280)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:888)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:388)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5522)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1092)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1984)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.core.web.Log4jServletContainerInitializer
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1892)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:197)

我的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>codingtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>codingtest</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
            <version>2.18.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>co.paralleluniverse</groupId>
            <artifactId>comsat-tomcat-loader</artifactId>
            <version>0.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

当我 运行 Eclipse 中的应用程序时,它可以正常工作。只有当我 运行 它在独立 Tomcat 7.

上时才会发生这个问题

更新

我注意到丢失的 class 被

使用了
<dependency>
            <groupId>co.paralleluniverse</groupId>
            <artifactId>comsat-tomcat-loader</artifactId>
            <version>0.1.1</version>
            <scope>runtime</scope>
        </dependency>

我尝试删除依赖项并在 Tomcat 7 上安装 war 文件。这次我得到了不同的错误

Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.util.descriptor.tld.TldParser
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1892)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
        ... 15 more

Feb 03, 2017 7:37:18 PM org.apache.catalina.startup.HostConfig deployWAR
SEVERE: Error deploying web application archive D:\apache-tomcat-7.0.73\webapps\ROOT.war
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:903)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1092)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1984)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

当我看指南时http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging 似乎很容易。但是在现实生活中并不是这样。

我在这里错过了什么?

使用 slf4j,Spring 引导自带 slf4j 和所有标准记录器,您不需要任何额外的依赖

$ jar tvf target/spring-boot-0.1.0.jar | egrep 'log|slf'
 41077 Tue Dec 13 18:07:58 GMT 2016 BOOT-INF/lib/slf4j-api-1.7.22.jar
470633 Fri Dec 09 11:03:02 GMT 2016 BOOT-INF/lib/logback-core-1.1.8.jar
 16521 Tue Dec 13 18:09:00 GMT 2016 BOOT-INF/lib/jcl-over-slf4j-1.7.22.jar
305137 Fri Dec 09 11:05:04 GMT 2016 BOOT-INF/lib/logback-classic-1.1.8.jar
 23647 Tue Dec 13 18:09:06 GMT 2016 BOOT-INF/lib/log4j-over-slf4j-1.7.22.jar
  2310 Thu Dec 22 23:48:14 GMT 2016 BOOT-INF/lib/spring-boot-starter-logging-1.4.3.RELEASE.jar
  4596 Tue Dec 13 18:09:14 GMT 2016 BOOT-INF/lib/jul-to-slf4j-1.7.22.jar
 66802 Thu May 28 09:49:34 BST 2015 BOOT-INF/lib/jboss-logging-3.3.0.Final.jar

Spring Boot 1.3 中删除了对 log4j(1) 的支持(参见 Release Notes)。因此,您可能在类路径中没有 log4j jar。但是仅将 jar 添加到类路径不会恢复 Spring Boot log4j 支持。

因此要么考虑使用受支持的日志记录框架,回滚 Spring 启动到低于 1.3 的版本(不真正推荐),要么使 log4j(1) 与 Spring 启动 1.5 一起工作。

更新:正如我现在注意到的,您没有使用 log4j1(我首先假设),但已经使用 log4j2。那没问题。在这种情况下,您可能必须遵循 Spring 引导说明,了解如何 Configure Log4j for logging.

抱歉给您指错了方向...

我做了以下修复

  1. 删除了 comsat-tomcat-loader 使用 log4j 的依赖项(感谢@FrVaBe)。

  2. 使用 SpringBootServletInitializer 扩展了我的 Spring 启动应用程序,如 docs.spring 中所述。io/spring-boot/docs/current/reference/html/