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

时间:2017-03-30 17:41:19

标签: java spring maven spring-boot spring-boot-maven-plugin

在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插件中生成uber jar,使其与版本1.3.9.RELEASE中的结构相同?

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

非常感谢任何帮助

由于 达明

5 个答案:

答案 0 :(得分:11)

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

<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>

答案 1 :(得分:2)

上面的答案

<layout>MODULE</layout>

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

  

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

但是由于我不想实现LayoutFactory,所以我尝试在下面的第二种解决方案中重新包装,并创建了一个额外的jar,并使用了给定名称的分类器:

  

这是由于Spring Boot 1.4中可执行jar的布局发生了变化。现在,应用程序类包装在BOOT-INF / classes中。   您的客户端模块取决于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的根目录具有类。

一个原始的jar具有与我想要的结构相同的

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

和第二个分类器的BOOT-INF /等具有较新的结构。

答案 2 :(得分:0)

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

令人讨厌的是,当我运行mvn spring-boot:run时,spring boot正常运行并运行应用程序!直到我们尝试部署到PCF(作为Spring-boot 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中删除了pluginManagement标签,我现在将获得./BOOT-INF结构。请记住,pluginManagement通常用于父pom结构,在该结构中您希望跨其他模块使用该插件的配置。

答案 3 :(得分:0)

在我的情况下,我使用的是Spring Boot 2.X,我在spring-boot-maven-plugin之后声明了maven-dependency-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>

答案 4 :(得分:0)

我使用的是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

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