当前位置: 首页 > 知识库问答 >
问题:

在Spring boot多模块项目fat jar中未执行液化脚本

洪育
2023-03-14

我有一个多模块Spring Boot应用程序,我已将其与Liquibase集成。从IDE运行它时,liquibase脚本工作正常。但是,当从jar运行它时,它们就不行了。经过一些调查,似乎liquibase本身在尝试从嵌入式jar读取时存在重大问题。liquibase脚本本身存在于胖jar内的嵌入式jar中,主xml文件如下所示:

<includeAll path="classpath*:config/liquibase/changelog/"/>

经过进一步的调查,我把一切都缩小到了液化本身的问题上。我使用的版本是liquibase-3.6.2。我怀疑liquibase中存在的bug在以下类中:liquibase。资源ClassLoaderResourceAccessor我将其缩小到的方法是

public Set<String> list(String relativeTo, String path, boolean includeFiles, boolean includeDirectories, boolean recursive) throws IOException

该方法的输入如下:

relativeTo = null
path = jar:file:/C:/#{SOME_PATH}/xxx-1.0.0.0-SNAPSHOT.jar!/BOOT-INF/lib/yyy-1.0.0.0-SNAPSHOT.jar!/config/liquibase/changelog/
includeFiles = true
includeDirectories = false
recursive = true

当然,您需要将#{SOME_PATH}替换为磁盘上的有效路径。为了安全起见,我把它删掉了。我们已经注意到,liquibase发现在胖jar xxx中的嵌入式yyy jar中可能有一些脚本。

这个方法的问题是,它不是返回jar中的XML脚本,而是返回yyy jar本身。这只会在稍后的代码中导致错误,因此我假设该方法负责查找XML文件(如果我直接从IDE而不是jar运行项目,则会成功地找到XML文件)。

我注意到的主要问题在第134行:

String returnPath = SpringBootFatJar.getSimplePathForResources(entry.getName(), path);

此时,路径变量已损坏,SpringBootFatJar返回损坏的返回路径。在接下来的部分中,我将描述会发生什么:

  • 在第105行,路径变量被拆分并成为“config/liquibase/changelog/”。基于它在第134行的使用方式和SpringBootFatJar类中的javadoc,这可能非常糟糕
  • 快进到第134行,入口。getName()返回“BOOT-INF/lib/yyy-1.0.0.0-SNAPSHOT.jar”,路径同上。基于SpringBootFatJar中的javadoc,这是非常糟糕的
  • 在第134行之后,returnPath变为“BOOT-INF/lib/yyy-1.0.0.0-SNAPSHOT.jar”,其余部分是历史记录,因为第143行的嵌套尝试永远不会以该路径开始

不幸的是,本周我没有时间进一步调查这个问题,我想在stackoverflow上发布这个问题,以查看是否还有其他人有这个问题,它是否是已知的liquibase错误,以及是否有简单的解决方案。下周我将尝试自己进一步调查它,并检查所有这些问题是否都来自第105行看似糟糕的拆分路径参数,因为输入的路径参数中有两个 "! /" 实例。

非常感谢。

共有2个答案

金秦斩
2023-03-14

如果其他人偶然发现这个问题,他们会在master上解决,但还并没有发布。我们所做的是从github中获取他们的主机并从中编译一个快照。撰写此评论的结果是3.7.0-SNAPSHOT。我们将使用官方的3.7.0版本,当他们得到它。

芮安顺
2023-03-14

显然,它仍然无法与当前的liquibase版本(3.8.5)配合使用。在spring boot胖罐中,不会从其他罐中获取变更日志。一种解决方法可能是覆盖SpringLiquibase。并手动更新jar列表。有关详细信息,请参见:http://www.it-surmann.com/spring-boot/fix-liquibase-includeall-in-a-spring-boot-project_1002.html

 类似资料:
  • 我有一个基本的SpringBoot应用程序。使用Spring初始值设定项、嵌入式Tomcat、Thymeleaf模板引擎,并将包作为可执行的JAR文件。是一个带有Spring Boot的多模块项目,该项目将有3个模块。这里是父模块pom。xml 这里是模块核心 这里是模块web: 从父根目录,我使用以下方法生成所有模块: 但问题是tdk-web-0.0.2-SNAPSHOT。jar不包含tdk-c

  • 父项目为demo-mybatis子模块为mybatis-dao、demo-service。demo-mybatis pom.xml如下: 4.0.0 pom mybatis-DAO Demo-service Demo-mybatis-app org.springframework.Boot spring-boot-starter-parent 2.3.2.release com.example D

  • 我有一个带有myapp-core和myapp-web模块的myapp父pom类型maven项目。myapp-core模块作为依赖项添加到MyApp-Web。 myapp-core模块中的所有类都位于根包com.myapp.core中,而myapp-web模块中的所有类都位于根包com.myapp.web中 主要的application.java也在com.myapp.web包中。由于我的核心模块根

  • 我有一个多模块maven项目。它的设置是正确的,因为当我运行maven clean install时,它成功地构建了所有模块。Webapp包含我需要在web服务中具备的通用功能,因此我将其作为maven依赖项包含在web服务中。 MavenReactor摘要: Eclipse甚至会将webapp项目到web服务的部署程序集。

  • 现在反应堆的建造顺序是 另外module2依赖于module1和module3依赖于module2,现在为了解释依赖关系,我使用${project.version}指定module2 pom中的module1版本,类似地,我使用module3 pom中的${project.version}引用module2。现在快照作业成功执行,但是当我尝试使用聚合器pom(它是所有模块的父pom)释放所有模块时

  • 项目模块化 在企业项目中,包层次和类关系比较负责,把代码拆分成模块是一个比较困难的任务,因为这需要你清晰的划分功能的边界,比如把业务逻辑和数据持久化拆分开来。 解耦和聚合 但你的项目符合高内聚低耦合时,模块化就变得很容易,这是一条非常好的软件开发实践。一个很好的模块化的例子就是Spring框架,spring框架提供了很多服务,比如MVC web框架、事务管理器、JDBC数据库连接等,下图展示了Sp