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/

完!

SpringBoot应用部署到Tomcat中无法启动问题的更多相关文章

  1. SpringBoot应用部署到Tomcat中无法启动问题(初识)

    参考http://blog.csdn.net/asdfsfsdgdfgh/article/details/52127562 背景 最近公司在做一些内部的小型Web应用时, 为了提高开发效率决定使用Sp ...

  2. springboot打包部署到tomcat

    一. springboot打成war包: 1. 首先查看是否为war 2. File----->ProjectStruture,选择Artifacts,中部点击“+”号 3. 按图中标记进行选择 ...

  3. eclipse:eclipse for java EE环境下如何配置tomcat服务器,并让tomcat服务器显示在控制台上,将Web应用部署到tomcat中

    eclipse环境下如何配置tomcat 打开Eclipse,单击"Window"菜单,选择下方的"Preferences".  单击"Server& ...

  4. UEditor在开发环境中正常运作,但是部署到Tomcat中却无法使用

    背景 ​ SpringBoot项目,在 JSP 中使用 UEditor 问题 ​ UEditor 在开发环境中正常运作,但是导致部署到 Tomcat 中却无法使用 原因 在开发环境中,路径不够严谨,多 ...

  5. vue项目如何部署到Tomcat中

    vue项目如何部署到Tomcat中 1,假设你要访问的项目名称为'hms' 2,在Tomcat的webapps下创建hms文件夹, 3,配置config/index.js文件,build: {} 选项 ...

  6. 多个springboot项目部署到tomcat,Error deploying web application archive

    每个springboot单独部署到tomcat下可以正常启动,多个一个就发生异常 Error deploying web application archive 解决:配置文件加上配置区分 sprin ...

  7. 【tomcat 无法部署】svn上下载的maven项目无法部署到tomcat中

    问题: svn上下载的maven项目无法部署到tomcat中,tomcat不识别项目,但是这个项目确实是web项目 发现的过程: 然后依次产看项目的编译版本: 项目的依赖架包: 才发现: 解决方法: ...

  8. MyEclipse2014中项目名更改后如何使用新的项目名部署到Tomcat中去

    在项目中调试的时候突然发现我复制的项目(项目名修改过了)部署在Tomcat中运行的时候还是显示的是原来的项目名,以至于我使用新的项目名称作为URL请求竟然是404,我去,当时感觉就不怎么好了. 当然, ...

  9. SpringBoot项目部署到tomcat

    SpringBoot部署到tomcat 一.修改maven.xml 1.添加<.packaging>war</.packaging>,打包为war包 <packaging ...

随机推荐

  1. Win32 SDK 编程开始, 创建窗口, 消息的处理, 消息循环

    Windows SDK 编程的一般步骤为: 1. 注册窗口类, 使用到的结构 WNDCLASSEX, 函数 RegisterClassEx. 2. 创建窗口, 函数 CreateWindowEx. 3 ...

  2. 一款很便捷很实用的框架——vue.js

    Hello,大家好!今天给大家带来一款十分好用的框架--vue.js! Vue.js是一套构建用户界面的渐进式框架.它 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 ...

  3. python进阶-------进程线程(二)

    Python中的进程线程(二) 一.python中的"锁" 1.GIL锁(全局解释锁) 含义: Python中的线程是操作系统的原生线程,Python虚拟机使用一个全局解释器锁(G ...

  4. Ansible(一) 配置安装

    puppet ruby开发 salt python开发,有客户端,使用Rabbitmq消息队列,支持并发,在机器数量很多时效果比ansible好. ansible python开发, 没有客户端,基于 ...

  5. 老男孩Python全栈开发(92天全)视频教程 自学笔记04

    day4课程目录: 逻辑运算符 while循环 day4课程内容梳理: 逻辑运算符 算数运算符:+,-,*,/,%,** 比较运算符:< ,>, ==,<=,>=,!=, 逻辑 ...

  6. 在VirtualBox 虚拟机中安装CentOS7 64位实验基础系统

    1.将CentOS-7-x86_64-Minimal ISO加载入虚拟机,选择安装CentOS 7 2.启动欢迎画面,保持默认,选择 继续 3.安装参数设置 3-1.设置时区以便同步时间,将时区更改为 ...

  7. 九、VueJs 填坑日记之在项目中使用jQuery

    很多人学习 js 都是从 jQuery 开始的,我也不例外.有时候进行一些操作的时候,还是感觉 jQuery 比较好用,那么,我们如何在项目中使用 jQuery 呢?这篇博文带你实践. 引用 jQue ...

  8. 深入浅出多线程——ReentrantLock (一)

    ReentrantLock是一个排它重入锁,与synchronized关键字语意类似,但比其功能更为强大.该类位于java.util.concurrent.locks包下,是Lock接口的实现类.基本 ...

  9. Android Studio 升级到3.0 提示 java.lang.NoClassDefFoundError

    Android Studio 升级到3.0 提示 java.lang.NoClassDefFoundError 这个问题折腾了2个小时,最后解决了,Stack Overflow 上也有一次类似的问题, ...

  10. Redis 高可用集群

    Redis 高可用集群 Redis 的集群主从模型是一种高可用的集群架构.本章主要内容有:高可用集群的搭建,Jedis连接集群,新增集群节点,删除集群节点,其他配置补充说明. 高可用集群搭建 集群(c ...