应用内置embeded tomcat,并打包为fat jar的解决方案

简介: 需求大量的微服务框架引起了一大波embeded tomcat,executable fat jar的潮流。显然spring boot是最出色的解决方案,但是spring boot有两个不足的地方:不支持配置web.xml文件,对于旧应用迁移不方便一些配置在web.xml里配置起来很直观,放到代码里配置就难搞清楚顺序了。

需求

大量的微服务框架引起了一大波embeded tomcat,executable fat jar的潮流。显然spring boot是最出色的解决方案,但是spring boot有两个不足的地方:

  • 不支持配置web.xml文件,对于旧应用迁移不方便
  • 一些配置在web.xml里配置起来很直观,放到代码里配置就难搞清楚顺序了。比如一些filter的顺序关系。
  • spring boot的方案依赖spring,对于一些轻量级的应用不想引入依赖

基于这些考虑,这里提出一个基于embeded tomcat本身的解决方案。

代码地址

https://github.com/hengyunabc/executable-embeded-tomcat-sample

支持特性:

  • 支持加载传统的web.xml配置
  • 支持打包为fat jar方式运行
  • 支持在IDE里直接运行

旧应用迁移步聚

旧应用迁移非常的简单

  • 在pom.xml里增加embeded tomcat的依赖
  • 把应用原来的src/main/webapp/WEB-INF 移动到 src/main/resources/WEB-INF下,把在src/main/webapp下面的所有文件移动到 src/main/META-INF/resources目录下
  • 写一个main函数,把tomcat启动起来

非常的简单,完全支持旧应用的所有功能,不用做任何的代码改造。

工作原理

web.xml的读取

传统的Tomcat有两个目录,一个是baseDir,对应tomcat本身的目录,下面有conf, bin这些文件夹。一个是webapp的docBase目录,比如webapps/ROOT 这个目录。

docBase只能是一个目录,或者是一个.war结尾的文件(实际对应不解压war包运行的方式)。

tomcat里的一个webapp对应有一个Context,Context里有一个WebResourceRoot,应用里的资源都是从WebResourceRoot 里加载的。tomcat在初始化Context时,会把docBase目录加到WebResourceRoot里。

tomcat在加载应用的web.xml里,是通过ServletContext来加载的,而ServletContext实际上是通过WebResourceRoot来获取到资源的。

所以简而言之,需要在tomcat启动之前,web.xml放到Context的WebResourceRoot,这样子tomcat就可以读取到web.xml里。

静态资源的处理

在Servlet 3.0规范里,应用可以把静态的资源放在jar包里的/META-INF/classes目录,或者在WEB-INF/classes/META-INF/resources目录下。

所以,采取了把资源文件全都放到src/main/META-INF/resources目录的做法,这样子有天然符合Servlet的规范,而且在打包时,自然地打包到fat jar里。

Fat jar的支持

Fat jar的支持是通过spring-boot-maven-plugin来实现的,它提供了把应用打包为fat jar,并启动的能力。具体原理可以参考另外一篇博客:http://blog.csdn.net/hengyunabc/article/details/50120001

当然,也可以用其它的方式把依赖都打包到一起,比如maven-assembly-plugin/jar-with-dependencies ,但不推荐,毕竟spring boot的方案很优雅。

其它

http://home.apache.org/~markt/presentations/2010-11-04-Embedding-Tomcat.pdf

官方的Embedded Tomcat文档

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/basic_app_embedded_tomcat/basic_app-tomcat-embedded.html

oracle的技术文档里的一个方案,但是这个方案太简单了,不支持在IDE里启动,不支持加载web.xml文件。

https://github.com/kui/executable-war-sample

这个把依赖都打包进war包里,然后在初始化tomcat里,直接把这个war做为docBase。这样子可以加载到web.xml。但是有一个严重的安全问题,因为应用的.class文件直接在war的根目录下,而不是在/WEB-INF/classes目录下,所以可以直接通过http访问到应用的.class文件,即攻击者可以直接拿到应用的代码来逆向分析。这个方案并不推荐使用。

实际上spring boot应用以一个war包直接运行时,也是有这个安全问题的。只是spring boot泄露的只是spring boot loader的.class文件。

相关文章
|
18天前
|
Java 应用服务中间件 Maven
Maven的三种项目打包方式——pom,jar,war的区别
Maven 提供了多种打包方式,分别适用于不同类型的项目。pom 用于父项目或聚合项目,便于项目的结构和依赖管理;jar 用于Java类库或可执行的Java应用程序;war 则专用于Java Web应用程序的部署。理解这些打包方式的用途和特点,可以帮助开发者更好地配置和管理Maven项目,确保构建和部署过程的顺利进行。无论是单模块项目还是多模块项目,选择合适的打包方式对于项目的成功至关重要。
53 3
|
4月前
|
Java Maven 容器
Maven使用IDEA自带工具打包,同时将lib下的jar包打入,双击jar包可直接运行
使用IntelliJ IDEA的Artifacts功能,可以将项目依赖的第三方jar包打包进jar文件中,实现双击jar包即可直接运行。
Maven使用IDEA自带工具打包,同时将lib下的jar包打入,双击jar包可直接运行
|
4月前
|
Java Maven
构建Springboot项目、实现简单的输出功能、将项目打包成可以执行的JAR包(详细图解过程)
这篇文章详细介绍了构建SpringBoot项目的过程,包括新建工程、选择环境配置、添加依赖、项目结构说明,并演示了如何编写一个简单的Controller控制器实现输出功能,最后讲解了如何使用Maven将项目打包成可执行的JAR包,并提供了运行JAR包的命令和测试效果。
构建Springboot项目、实现简单的输出功能、将项目打包成可以执行的JAR包(详细图解过程)
|
5月前
|
Java 应用服务中间件
tomcat7 与 tomcat8 加载 jar包的顺序
tomcat7 与 tomcat8 加载 jar包的顺序
183 0
|
6月前
|
XML 运维 Java
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
56 1
|
6月前
|
Java Maven
Maven项目打包成jar项目后运行报错误: 找不到或无法加载主类 Main.Main 和 jar中没有主清单属性解决方案
Maven项目打包成jar项目后运行报错误: 找不到或无法加载主类 Main.Main 和 jar中没有主清单属性解决方案
945 0
|
5月前
|
Java
[JarEditor]可直接修改jar包的IDEA插件
### 修改JAR包变得更简单:JarEditor插件简介 **背景:** 开发中常需修改JAR包中的class文件,传统方法耗时费力。JarEditor插件让你一键编辑JAR包内文件,无需解压。 **插件使用:** 1. **安装:** 在IDEA插件市场搜索JarEditor并安装。 2. **修改class:** 打开JAR文件中的class,直接编辑,保存后一键构建更新JAR。 3. **文件管理:** 右键菜单支持在JAR内新增/删除/重命名文件等操作。 4. **搜索:** 使用内置搜索功能快速定位JAR包内的字符串。
491 2
[JarEditor]可直接修改jar包的IDEA插件
|
5月前
|
弹性计算 Java Serverless
Serverless 应用引擎操作报错合集之上传自定义JAR包,启动时报错,是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
5月前
|
关系型数据库 Java 分布式数据库
PolarDB产品使用问题之部署到服务器上的Java应用(以jar包形式运行)无法连接,如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。