Spring Boot Maven 插件 - 没有 BOOT-INF 目录



在 spring-boot-maven-plugin 的 1.3.8.RELEASE 版本和 1.4.0.RELEASE 之间 - 生成的包结构发生了变化(如果您提取 uber jar 文件) 1.3.8.RELEASE com, lib, META-INF 和 org 目录 1.4.0.Release 有一个 BOOT-INF、META-INF 和 ORG 目录 基本上从 1.4.0.RELEASE 开始 - 所有的类和库都在 BOOT-INF 目录中。 因此,当您尝试在Amazon Lambda上运行Spring Boot项目时,它说找不到一个jar,因为它无法读取新的Spring Boot Uber jar结构

我的问题是 - 在较新版本的 Spring Boot Maven 插件中是否有可能让它生成与版本 1.3.9.RELEASE 中相同的结构的 uber jar?

我尝试了 maven-shade-plugin - 但这会导致其他问题

任何帮助都非常感谢

谢谢 戴民

解决方案是在pom.xml文件中添加插件的模块布局

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>MODULE</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>

就我而言,我使用的是 Spring boot 2.X,我在maven-dependency-plugin之后声明了spring-boot-maven-plugin(我曾经在 Docker 中解压缩和创建分解的应用程序),它必须在解包之前,这是有道理的,它是在 spring boot maven 插件执行之前解压缩的。下次我会在插件链中声明它的第一件事,为此损失了 1 个多小时。希望它对某人有所帮助。

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${spring.boot.mainClass}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

上面的答案是

<layout>MODULE</layout>

不再工作,这是因为布局元素在 Spring Boot 2.x 中已弃用。 我正在使用Spring Boot 2.0.x,我在github上发现了这个有用的评论:

在 Spring Boot 2.0 中删除了对模块布局的支持,在 1.5 中已弃用。不幸的是,错过了对Maven插件文档的更新,因此我们可以使用此问题来解决此问题。您应该改用自定义 LayoutFactory。

但是由于我不想实现 LayoutFactory,我尝试了下面的第二个解决方案,它实际上重新打包并创建了一个带有分类器名称的额外 jar:

这是由于 Spring Boot 1.4 中可执行 jar 布局的变化。应用程序类现在打包在 BOOT-INF/类中。 您的客户端模块依赖于 Web 模块的重新打包的胖罐子。由于新的布局,这意味着客户端模块无法再加载 Web 模块的类。如果要将 Web 模块用作依赖项,则应配置 Boot 的重新打包以将分类器应用于胖罐。例如:

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

这样做将允许其他模块依赖于原始 jar,该 jar 不嵌入模块的依赖项,并将类放在 jar 的根目录中。

一个原始罐子的结构与我想要的相同

com.my-package.foo.bar
META-INF

第二个分类器具有更新的结构,带有 BOOT-INF/等。

对我来说,解决方案有点阴险......我将 spring-boot-maven-plugin 嵌套在 pluginManagement 下(见下文)。咚!

令人讨厌的是,当我运行 mvn spring-boot:run 时,弹簧启动就好了,并运行应用程序! 直到我们尝试部署到 PCF(作为弹簧启动 JAR),我们才收到一个错误,即二进制文件的格式有问题......

<build>
<!-- 
DON'T DO THIS!! 
-->
<pluginManagement>
<plugins>             
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>            
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>                        
</plugin>                                     
</plugins>
</pluginManagement>
<!-- 
DO THIS INSTEAD!! 
-->      
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>            
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>                        
</plugin>                         
</plugins>
</build>

一旦我从 POM 中删除了插件管理标签,我现在将获得 ./BOOT-INF 结构。 请记住,pluginManagement 通常用于父 pom 结构,您希望该插件的配置在其他模块中使用。

我使用的是Gradle,而不是Maven,这就是我必须做的:

1-在我的build.gradle中,我添加了 https://spring.io/guides/gs/spring-boot-Docker/中定义的以下属性。

buildscript {
...
dependencies {
...
classpath('gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0')
}
}
group = 'springio'
...
apply plugin: 'com.palantir.docker'
task unpack(type: Copy) {
dependsOn bootJar
from(zipTree(tasks.bootJar.outputs.files.singleFile))
into("build/dependency")
}
docker {
name "${project.group}/${bootJar.baseName}"
copySpec.from(tasks.unpack.outputs).into("dependency")
buildArgs(['DEPENDENCY': "dependency"])
}

2-我的依赖项文件夹未写入

ARG DEPENDENCY=target/dependency

相反,我将其定位在另一个文件夹中,因此我在 Dockerfile 中更改了此属性:

ARG DEPENDENCY=build/dependency

有了这个,我得到了一个成功的构建。

最新更新