文章目录
- 在使用Spring Boot的时候Jar包转为war包出现的几种问题与我的解决方法
- 项目介绍
- 转换方式
- Netty对于Tomcat部署的干扰
- 问题
- 原因
- 解决方法
- 注意
- 参考
在使用Spring Boot的时候Jar包转为war包出现的几种问题与我的解决方法
在之前使用Spring Boot的情况下,基本都是采用Jar包部署的方式,打包成XXX.jar的形式,使用java -jar XXX.jar的形式来运行,今天想转变成war包放入tomcat来进行部署,出现诸多问题,记录下来,以后方便解决。
项目介绍
一个公司的Spring Boot项目,但是包含有一个Netty实现的Socket Server,用来与硬件端进行通信,与web的8080端口分开,socket的端口为9911;
转换方式
方式非常简单,baidu和谷歌都能找到非常多的答案
- 启动类修改
启动类继承 SpringBootServletInitializer,并且@Override configure方法
参考如下:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
- pom.xml修改【Maven修改】
打开pom.xml文件,主要的修改地方有两处
①打包方式声明修改
<packaging>jar</packaging>
修改为
<packaging>war</packaging>
如果使用的是Gradle,修改如下:
apply plugin: 'war'
②在依赖中【也就是】中添加如下代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
如果使用的是Gradle,修改如下:
dependencies {
// …
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
// …
}
- 这一步的目的在于确保嵌入式servlet容器不会干扰部署war文件的servlet容器。其实这里不加也可以正常的部署成功,但是为了消除干扰,请添加。
- 需要注意的是,添加如下代码之后,使用Spring
的启动类就无法启动项目了,需要采用Maven的方式启动。 - Idea直接在maven的侧边栏中找到Plugins下的spring-boot中的run执行就可以了,也可以采用maven命令的方式执行。
不过maven执行的方式没有日志着色,很难看,所以笔者选择调试的时候把这段话给注释掉。或者更改scope属性应该也可以。
Netty对于Tomcat部署的干扰
- 笔者之前的项目采用jar的方式运行无问题。
- 修改为war包后无论怎么修改也无法执行,是因为项目中添加了Netty作为Socket的服务端,导致使用tomcat部署的时候显示部署成功,日志正常,但是访问页面始终失败,其中有404问题,也有页面始终在加载,但是最终失败的情况。
- 其实原因也非常的简单,但是笔者一开始并没有想到,还是被jar包的运行无问题给局限住了。
问题
Netty监听端口导致tomcat假死,访问web页面失败;tomcat关闭异常,netty始终监听此端口,必须强制杀死进程才能关闭。
原因
因为Netty里面的sync()方法是阻塞的,可以理解成启动此部分之后,由Netty这个通信框架来接管了;而且Netty所监听的端口必须与tomcat的端口不一致。
解决方法
- 最好的方法当然是把Netty这个框架剔除出去,单独设定为一个服务,这样更加的整洁统一。
- 如果一定要放在一起呢?
那么可以采用线程的方式来启动Netty,这样就可以了。
经测试,tomcat部署成功。 - 下一步还是会把Netty独立出来,web项目仅作为客户端,Netty单独作为一个服务器实现转发。
注意
- 也有部分人喜欢在spring-boot-starter-web剔除spring-boot-starter-tomcat,但是我自己测试,效果是一致的,Spring的官方文档中是采取文中内容的方式。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--<!– 移除嵌入式tomcat插件 –>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>-->
</dependency>