使用 Spring-Boot 创建一个简单的 JAR 而不是可执行的 JAR

Posted

技术标签:

【中文标题】使用 Spring-Boot 创建一个简单的 JAR 而不是可执行的 JAR【英文标题】:Create a simple JAR instead of an executable JAR with Spring-Boot 【发布时间】:2016-11-13 17:24:53 【问题描述】:

我遇到了多模块 Spring-Boot 应用程序的问题。

我有一个用于服务的模块,即 core-Module。还有一个视图相关类的模块,web-Module。 它们都在 parent-Module 中,我在其中添加了依赖项,例如“spring-boot-starter”,两个模块都可以使用。

现在问题来了:

我想使用嵌入式 Tomcat 运行 web-Module,并将 core-Module 作为 web-module 中的依赖项.

在其他 Spring 项目中,我将只包含 maven-jar-plugin 并创建一个 core-Module 的 jar。

这个 Spring-Boot 项目的问题是 maven-jar-plugin 已经在“spring-boot-starter”中配置好了。它需要一个 mainClass,只有 web 模块才有。

摘自“spring-boot-starter”-POM

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>$start-class</mainClass>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

有没有办法将 core-Module 打包为 JAR,而不需要在该模块中添加“start-class”?

【问题讨论】:

如果你搜索spring boot non executable jar,你会在Spring Boot文档中找到Create a non-executable JAR with exclusions。 @Andreas 问题是这仍然需要 mainClass-Attribute。由于配置在 Spring 文件中。我在原始问题中附加了 Spring-Configuration。 【参考方案1】:

您似乎可以通过配置 spring-boot-maven-plugin 来禁用 fat-JAR 替换原来的并安装到 repo 中。

取自http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/maven-plugin/examples/repackage-disable-attach.html

默认情况下,重新打包目标会将原始工件替换为 可执行文件。如果您只需要部署原始 jar 和 仍然能够使用常规文件名运行您的应用程序,配置 插件如下:

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>1.5.1.RELEASE</version>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
            <configuration>
              <attach>false</attach>
            </configuration>
          </execution>
        </executions>
        ...
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

此配置将生成两个工件:原始工件和重新打包目标生成的可执行对应部分。只会安装/部署原始版本。

【讨论】:

完美解决方案。【参考方案2】:

您可以通过这种方式禁用 spring-boot-maven 插件。

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </execution>
            </executions>
        </plugin>

【讨论】:

【参考方案3】:

创建简单的 jar 更新

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <classifier>exec</classifier>
        </configuration>
    </plugin>

欲知更多详情,请访问以下 Spring URL:- https://docs.spring.io/spring-boot/docs/1.1.2.RELEASE/reference/html/howto-build.html

【讨论】:

【参考方案4】:

我找到了答案。 我像@judgingnotjudging 解释的那样配置了我的应用程序。不同之处在于我把它放在了 parent-POM 中:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

它阻止了在子模块中默认创建 JAR。我可以通过在 web-Module 中包含这个 only 来解决这个问题。

这样,Spring-Boot 从 web-Module 构建一个 fat-JAR,从 core-Module 构建一个简单的 JAR。

【讨论】:

【参考方案5】:

你可以简单地改变

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>

【讨论】:

不包括魔法 maven 插件似乎是一个对我有用的简单解决方案。【参考方案6】:

我不知道它是否仍然相关,但是,需要为 spring-boot-maven-plugin 配置一个简单的分类器-

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

这将生成两个 jar - 一个是可以作为依赖项包含的普通 jar,另一个是作为后缀附加“exec”字的 exe jar - 例如 test-0.0.1-SNAPSHOT-exec.jar 和test-0.0.1-SNAPSHOT.jar

【讨论】:

【参考方案7】:

如果您使用嵌入式 tomcat 运行您的应用程序,您不只需要一个标准 Spring Boot fat jar 用于您的 Web 应用程序吗?如果是这样,只需在 pom 中将您的 web 模块标记为依赖于您的核心模块,然后构建您的项目。

是否有不同的用例需要将罐子分开?

您是将模块构建为完全独立的模块还是作为单个多模块项目的一部分?区别在于后者,您将在根目录中有一个 pom 来指定模块。我特别忘记了 Maven 语法,所以我的示例是 Gradle(用于多模块构建的 Maven 文档是 here)。对此感到抱歉。

baseProject
|----web-module
|----core-module

baseProject 的 build.gradle:

project(':web-module') 
    dependencies 
        compile project(':core-module')
    
    evaluationDependsOn(':core-module')


Maven 具有类似的结构。您应该查看文档,但我相信您需要做的就是在您的父 pom 中正确指定模块顺序,如下所示,并将依赖项包含在您的 web-module pom 中。

父pom:

...
<modules>
    <module>core-module</module>
    <module>web-module</module>
</modules>

web-pom:

<project ...>

<parent>
    <groupId>com.example</groupId>
    <artifactId>simple-parent</artifactId>
    <version>1.0</version>
</parent>

<artifactId>web-module</artifactId>
<packaging>war</packaging>
<name>My web-module</name>
<dependencies>

...
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>core-module</artifactId>
        <version>1.0</version>
    </dependency>
</dependencies>
...

核心 pom 应该只需要像上面的 web 模块一样包含 parent 部分,否则相同。

【讨论】:

我想使用 web-module 作为 fat-JAR 并将 core-module 作为依赖项。要将 core 模块作为依赖项,我需要能够创建一个可以安装在 .m2 目录中的“产品”。也许有更简单的方法来实现这一点。 @Johannes Esseling 我更新了我的答案,包括构建一个多模块项目。听起来您希望将核心模块发布到存储库然后检索它。您可以通过将项目创建为多模块项目来避免这种情况。

以上是关于使用 Spring-Boot 创建一个简单的 JAR 而不是可执行的 JAR的主要内容,如果未能解决你的问题,请参考以下文章

Spring-boot简单的理解

Spring-Boot:Profile简单示例

在 spring-boot 项目中使用 spring mvc xml 项目

spring-boot实战09:Spring Boot中使用@Scheduled创建定时任务

spring-boot处理jackson的null值

使用 spring-boot 的 assemble 创建的 jar 的 Gradle 集名称