1. 程式人生 > >springboot:修改內建tomcat版本

springboot:修改內建tomcat版本

一般情況下,完全沒有必要去修改 tomcat 的版本,就算是生產環境使用的 spring boot 內建版本,也是最好使用 spring boot的內建的 tomcat 版本,這是經過相容測試、迴歸測試的版本號。可能有的同學會說,生產環境下還不敢冒險去使用最新版的 tomcat,萬一出現什麼么蛾子呢?很多公司接受不起生產環境的這種巨大損失,尤其是涉及到金融方面的。所以因循守舊,想要使用經過很多大公司校驗的 tomcat 7,甚至是 tomcat 6;當然,不排除這種可能性。比如我司現在生產環境的 tomcat 版本就是7.0.x,而 tomcat 的開發穩定版現在已經到 9.0.6(當前時間:2018年3月14日)。但是另一方面,隨著版本的提升,依賴於 tomcat 的良好架構設計,其後續版本的各種效能提升,對於 http 2的支援,難道你真的捨得不去嘗試使用嗎?
廢話說完。
下來詳細講講怎麼修改 tomcat 的版本吧,也是去試著理解一下 tomcat 的啟動過程,以及 spring boot 如何內嵌整合 tomcat 的。
想要修改內建的 tomcat 的預設版本,首先得知道當前是什麼版本。
比如我當前的 sb 版本是:

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

    
    
  • 1
  • 2
  • 3
  • 4
  • 5

藉助於 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可知所有的 jar。
此時如果是 eclipse 的忠實使用者,則可以在當前工程 project 的 maven 依賴裡面直接去看 jar 的版本號。

IDEA 則略有不同,IDEA 的 module 概念等於 eclipse 的 project 概念。IDEA 在 External Libraries下面並不能看到版本號資訊,尤其是對於多個 module 的工程 project 而言,不同 module 使用不同的 tomcat 版本時如何知道當前 module 使用的是什麼版本的 tomcat 呢?
External Libraries
實際上,此時就是要去理解 IDEA 的設計意圖咯,我認為 External Libraries 的作用主要是去看原始碼,debug。在右側還有一個面板 Maven Projects,找到當前 module,開啟 dependencies 資訊,然後此時還可以檢視 jar 包,即 artifactId 的依賴管理關係:
這裡寫圖片描述
可知 spring boot 1.5.7 的內建 tomcat 版本是 8.5.20。

方法2:不借助於 IDE 的情況下, 怎麼知道版本資訊?
開啟檔案:
/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

    
  • 1
  • 2
  • 3
  • 4
  • 5

但是,有時候啟動會報錯:

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

    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

顯然是缺少 jar 包,在 dependency 裡面新增即可。

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

    
    
  • 1
  • 2
  • 3
  • 4
  • 5

但是還有另外一個 artifactId

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

    
    
  • 1
  • 2
  • 3
  • 4
  • 5

使用下面這個更好?(待驗證)

但是,還有一個問題:
我們知道spring-boot-starter-web是包含spring-boot-starter-tomcat的,檢視 pom 檔案可知:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-validator</artifactId>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
	</dependency>
</dependencies>

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

也就是說,我們沒有必要重複新增spring-boot-starter-tomcat,一個spring-boot-starter-web就可以把一個典型的 spring web 專案搭建成功。也方便了 jar 包的管理。
但是,如果此時你的專案中僅僅新增spring-boot-starter- web,而沒有直接新增spring-boot-starter-tomcat,就算配置

<properties>
    <tomcat.version>9.0.6</tomcat.version>
    <!--<tomcat.version>8.0.30</tomcat.version>-->
</properties>

    
    
  • 1
  • 2
  • 3
  • 4

也並不能生效。至於為什麼,有待研究 spring boot 的 autoconfigure 原始碼才能知道吧。

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-778f64ae39.css" rel="stylesheet">
            </div>

一般情況下,完全沒有必要去修改 tomcat 的版本,就算是生產環境使用的 spring boot 內建版本,也是最好使用 spring boot的內建的 tomcat 版本,這是經過相容測試、迴歸測試的版本號。可能有的同學會說,生產環境下還不敢冒險去使用最新版的 tomcat,萬一出現什麼么蛾子呢?很多公司接受不起生產環境的這種巨大損失,尤其是涉及到金融方面的。所以因循守舊,想要使用經過很多大公司校驗的 tomcat 7,甚至是 tomcat 6;當然,不排除這種可能性。比如我司現在生產環境的 tomcat 版本就是7.0.x,而 tomcat 的開發穩定版現在已經到 9.0.6(當前時間:2018年3月14日)。但是另一方面,隨著版本的提升,依賴於 tomcat 的良好架構設計,其後續版本的各種效能提升,對於 http 2的支援,難道你真的捨得不去嘗試使用嗎?
廢話說完。
下來詳細講講怎麼修改 tomcat 的版本吧,也是去試著理解一下 tomcat 的啟動過程,以及 spring boot 如何內嵌整合 tomcat 的。
想要修改內建的 tomcat 的預設版本,首先得知道當前是什麼版本。
比如我當前的 sb 版本是:

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

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

藉助於 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>

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可知所有的 jar。
此時如果是 eclipse 的忠實使用者,則可以在當前工程 project 的 maven 依賴裡面直接去看 jar 的版本號。

IDEA 則略有不同,IDEA 的 module 概念等於 eclipse 的 project 概念。IDEA 在 External Libraries下面並不能看到版本號資訊,尤其是對於多個 module 的工程 project 而言,不同 module 使用不同的 tomcat 版本時如何知道當前 module 使用的是什麼版本的 tomcat 呢?
External Libraries
實際上,此時就是要去理解 IDEA 的設計意圖咯,我認為 External Libraries 的作用主要是去看原始碼,debug。在右側還有一個面板 Maven Projects,找到當前 module,開啟 dependencies 資訊,然後此時還可以檢視 jar 包,即 artifactId 的依賴管理關係:
這裡寫圖片描述
可知 spring boot 1.5.7 的內建 tomcat 版本是 8.5.20。

方法2:不借助於 IDE 的情況下, 怎麼知道版本資訊?
開啟檔案:
/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

  
  • 1
  • 2
  • 3
  • 4
  • 5

但是,有時候啟動會報錯:

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

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

顯然是缺少 jar 包,在 dependency 裡面新增即可。

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

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

但是還有另外一個 artifactId

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

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

使用下面這個更好?(待驗證)

但是,還有一個問題:
我們知道spring-boot-starter-web是包含spring-boot-starter-tomcat的,檢視 pom 檔案可知:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-validator</artifactId>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
	</dependency>
</dependencies>

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

也就是說,我們沒有必要重複新增spring-boot-starter-tomcat,一個spring-boot-starter-web就可以把一個典型的 spring web 專案搭建成功。也方便了 jar 包的管理。
但是,如果此時你的專案中僅僅新增spring-boot-starter- web,而沒有直接新增spring-boot-starter-tomcat,就算配置

<properties>
    <tomcat.version>9.0.6</tomcat.version>
    <!--<tomcat.version>8.0.30</tomcat.version>-->
</properties>

  
  
  • 1
  • 2
  • 3
  • 4

也並不能生效。至於為什麼,有待研究 spring boot 的 autoconfigure 原始碼才能知道吧。

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-778f64ae39.css" rel="stylesheet">
            </div>