草庐IT

Spring Boot系列之修改内置Tomcat版本

普通网友 2023-04-28 原文

背景

在 spring boot 出来之前,或者没有使用 spring boot 时,Java EE 开发时如果选择 tomcat servlet,需要自己指定 tomcat 版本;此处没有考虑那种直接把打包的 war 直接扔到本地安装的任意版本的 tomcat,然后启动外置 tomcat 的情况。

使用 spring boot (内置 tomcat)时,一般情况下,完全没有必要去修改 tomcat 的版本,就算是生产环境使用的 spring boot 内置版本,也是最好使用 spring boot 的内置的 tomcat 版本,这是经过兼容测试、回归测试的版本号。

但是,很多公司都不推荐各个应用使用内置 tomcat 这种方式,因为这样的话,100 个服务,可能有几十种版本的 tomcat,不方便统一管理,太老的 tomcat 版本有问题,太新的版本不稳定。所以很多公司仍然在使用经过很多公司多年生产环境校验的 tomcat 7,甚至是 tomcat 6。随着版本的提升,依赖于 tomcat 的良好架构设计,其后续版本的各种性能提升,对于 http 2的支持,难道你真的舍得不去尝试使用吗?

不过,本地开发时,完全可以随意使用最新版本的 tomcat,如果是使用 spring boot,并且是使用内置 tomcat 的话,直接使用最新版本的 sb 即可,因为每次 sb 升级,都会升级 tomcat 版本。但是最新版本 sb 可能有不兼容等问题,有些人可能不会去尝试使用。

如果不是使用 spring boot 内置 tomcat,而是想使用任意版本的 tomcat 呢?

下来详细讲讲怎么修改 tomcat 的版本吧,也是去试着理解一下 tomcat 的启动过程,以及 spring boot 如何内嵌集成 tomcat 的。
想要修改内置的 tomcat 的默认版本,首先得知道当前是什么版本。

如何知道当前使用的版本

方法1:借助于IDEA

比如我当前的 sb 版本是:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
</parent>

借助于 IDE,查看 spring-boot-starter-tomcat 的 pom 文件:

<dependencies>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-core</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-el</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-websocket</artifactId>
	</dependency>
</dependencies>

可知所有的 jar。
此时如果是 eclipse 的忠实用户,则可以在当前工程 project 的 maven 依赖里面直接去看 jar 的版本号。

IDEA 则略有不同,IDEA 的 module 概念等于 eclipse 的 project 概念。IDEA 在 External Libraries下面并不能看到版本号信息,尤其是对于多个 module 的工程 project 而言,不同 module 使用不同的 tomcat 版本时如何知道当前 module 使用的是什么版本的 tomcat 呢?

实际上,此时就是要去理解 IDEA 的设计意图咯,我认为 External Libraries 的作用主要是去看源码和用于debug。在右侧还有一个面板 Maven Projects,找到当前 module,打开 dependencies 信息,然后此时还可以查看 jar 包,即 artifactId 的依赖管理关系:

可知 spring boot 1.5.7 的内置 tomcat 版本是 8.5.20。

方法2:没有IDE, 怎么知道版本信息?

打开本地maven repository目录下的spring-boot-dependencies文件:
/Users/awesome-me/.m2/repository/org/springframework/boot/spring-boot-dependencies/1.5.7.RELEASE/spring-boot-dependencies-1.5.7.RELEASE.pom
可以在标签<properties>下面找到<tomcat.version>8.5.20</tomcat.version>

修改内置的默认版本

从上面的方法2,就知道如何修改的思路。
即在 pom.xml 文件里面添加一个标签<properties>,添加期望的版本<tomcat.version>8.0.30</tomcat.version>
如何知道修改是否成功?
修改成<tomcat.version>8.0.30</tomcat.version>
启动信息:

2018-03-15 00:46:26.275  INFO 47112 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-03-15 00:46:26.282  INFO 47112 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-03-15 00:46:26.283  INFO 47112 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.30
2018-03-15 00:46:26.333  INFO 47112 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-03-15 00:46:26.333  INFO 47112 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1000 ms

但是,有时候启动会报错:

Caused by: java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory 
  at org.apache.catalina.util.LifecycleBase.<clinit>(LifecycleBase.java:37) 
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:169) 
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) 
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) 
  ... 13 common frames omitted

显然是缺少 jar 包,在 dependency 里面添加以下两者之一即可:

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

如果项目是使用内嵌Tomcat servlet容器形式打包部署,推荐使用下面这个,其groupId和artifactId皆是embed类型的jar包。如果项目是以war包形式打包部署,即pom标签是war,则推荐使用上面这个。

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

但是,还有一个问题:
spring-boot-starter-web是包含spring-boot-starter-tomcat的,查看 pom 文件可知。
也就是说,我们没有必要重复添加spring-boot-starter-tomcat,一个spring-boot-starter-web就可以把一个典型的 spring web 项目搭建成功,也方便 jar 包的管理,此时需要额外添加Tomcat的GA:

<properties>
	<tomcat.version>8.0.30</tomcat.version>
</properties>
<!-- 显式指定Tomcat版本 -->
<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>${tomcat.version}</version>
</dependency>

有关Spring Boot系列之修改内置Tomcat版本的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  5. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  6. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  7. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. Tomcat AJP 文件包含漏洞(CVE-2020-1938) - 2

    目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控

  10. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

随机推荐