zoukankan      html  css  js  c++  java
  • SpringBoot应用部署到Tomcat中无法启动问题

    SpringBoot应用部署到Tomcat中无法启动问题

     

     

    背景

    最近公司在做一些内部的小型Web应用时, 为了提高开发效率决定使用SpringBoot, 这货自带Servlet容器, 
    你在开发Web应用时可以直接在本地像运行控制台应用一样启动,省去了重复部署的时间;配置上相比于SpringMVC也是有了大大的简化。SpringBoot的应用可以直接打成一个可运行的jar包, 
    你无需发愁为了不同应用要部署多个Tomcat。但是实际部署时你会发现打成Jar包的方式有一个致命的缺点, 
    当你改动了一个资源文件、或者一个类时, 打要往服务器重新上传全量jar包。比如网速慢的公司(比如我们)来说, 那简直是不能忍受的!!!

    还好SpringBoot也支持打包成普通的war包, 
    这样你本地开发环境直接用控制台方式运行,部署到服务器时打成普通war包部署。这样既享受到了SpringBoot开发带来的快感, 
    又避免了增量部署不方便的问题。可谓两全其美。 不过在打成War包时, 我也遇到了一些问题

    问题描述

    我修改pom.xml将打包方式改成war

    <packaging>war</packaging>

    完事儿打完包以后, 放到我本地Tomcat上跑了跑,发现没问题。但是部署到服务器上的Tomcat以后, 发现无法启动,错误如下:

    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[
    /report]]
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
            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:471)
            at java.util.concurrent.FutureTask.run(FutureTask.java:262)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
            at org.apache.tomcat.websocket.server.WsServerContainer.<init>(WsServerContainer.java:150)
            at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
            at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)
            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5573)
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
            ... 10 more

    明显不是应用代码错误,猜想应该是环境问题。经过分析, 我本地的Tomcat版本是8.0.28, 而服务器上的Tomcat是7.0.69。 我在本地下了个Tomcat7.0.70部署也报同样错误。更加确定问题跟Tomcat版本有关。经过多方查找资料,最后在Stackoverflow上看到一个老外说SpringBoot默认Servlet容器是基于Tomcat8的

    在打好的war包中确实发现了Tomcat相关jar包,而且是Tomcat8的,拿Tomcat8的embed包在Tomcat7下面那肯定是不能用啊 
    这里写图片描述

    要支持低版本Tomcat需要在maven中指定Tomat版本,配置如下:

    <properties>
        <tomcat.version>7.0.69</tomcat.version>
    </properties>
    • 1
    • 2
    • 3

    然后依赖中加上(这个其实不加也行, 官方文档是加上的)

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-juli</artifactId>
        <version>${tomcat.version}</version>
    </dependency>

    加上以后试了下,果然是没问题了。看了下war包中的lib目录,确实已经变成Tomcat7的包了 
    这里写图片描述

    但是我还是有点疑惑, 这样配置打成包岂不是换个Tomcat版本就要重新打次包? 既然是由于SpringBoot内部的Servlet容器造成了这个限制, 那我不用行不行? 又查了很多资料, 还真有办法!

    <!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

    试了下, 加上这个后, 上面说Tomcat的版本无需指定了, 耶! ^_^


    总结

    总结下SpringBoot应用部署到Tomcat下的配置方法用于备忘也方便遇到同样问题的朋友

      1. 将打包方式改成war 
        这个没啥好说的, 肯定要改成war

      2. 配置嵌入Tomcat中的方式 
        这里有两种方式可选择:

        方式一:用spring-boot内置的tomcat库, 并指定你要部署到Tomcat的版本

        <properties>
            <tomcat.version>7.0.69</tomcat.version>
        </properties>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
      3. 方式二:不用spring-boot内置的tomcat库(强烈推荐这种方式!!)

        <!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

    1. maven-war-plugin (可选) 
      与maven-resources-plugin类似,当你有一些自定义的打包操作, 比如有非标准目录文件要打到war包中或者有配置文件引用了pom中的变量。 具体用法参见官方文档:http://maven.apache.org/components/plugins/maven-war-plugin/

    完!

  • 相关阅读:
    《应用Yii1.1和PHP5进行敏捷Web开发》学习笔记(转)
    YII 小模块功能
    Netbeans代码配色主题大搜集
    opensuse 启动巨慢 解决方法 90s多
    opensuse 安装 网易云音乐 rpm netease music
    linux qq rpm deb opensuse
    openSUSE 安装 alien
    第一行代码 Android 第2版
    Android Studio AVD 虚拟机 联网 失败
    docker error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuratio
  • 原文地址:https://www.cnblogs.com/a8457013/p/7687764.html
Copyright © 2011-2022 走看看