【问题标题】:How to add a dependency to a Spring Boot Jar in another project?如何在另一个项目中向 Spring Boot Jar 添加依赖项?
【发布时间】:2017-02-26 14:49:27
【问题描述】:

我有一个 Spring Boot 应用程序,并用它创建了一个 Jar。以下是我的pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-java8time</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- WebJars -->
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.6.2</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

我想在我的其他应用程序中使用这个 Jar,所以将此 jar 添加到我的应用程序中。但是当我在那个 Jar 中调用一个方法时,它会抛出一个ClassNotFoundException

我该如何解决这个问题?如何向 Spring Boot JAR 添加依赖项?

【问题讨论】:

  • 您不能将 spring-boot-plugin-manipulated-jar 用作“正常”依赖项,因为它的结构已更改为“可启动”作为 Spring 的独立 JAR。我建议将两个应用程序所需的代码提取到一个单独的非 Spring-boot(如此传统的库 JAR)模块中。
  • 对于 Spring Boot 2stackoverflow.com/a/55722135/1654265

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


【解决方案1】:

默认情况下,Spring Boot 将你的 JAR 重新打包成一个可执行的 JAR,它通过将你的所有类放在 BOOT-INF/classes 中,并将所有依赖库放在 BOOT-INF/lib 中来做到这一点。创建这个胖 JAR 的后果是您不能再将它用作其他项目的依赖项。

来自Custom repackage classifier

默认情况下,repackage 目标将用重新打包的工件替换原始工件。对于代表应用程序的模块来说,这是一种正常的行为,但是如果您的模块被用作另一个模块的依赖项,则需要为重新打包的模块提供一个分类器。

原因是应用程序类被打包在BOOT-INF/classes中,因此依赖模块无法加载重新打包的jar的类。

如果您想保留原来的主要工件以便将其用作依赖项,您可以在repackage 目标配置中添加classifier

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

使用此配置,Spring Boot Maven 插件将创建 2 个 JAR:主要的 JAR 将与通常的 Maven 项目相同,而第二个将附加分类器并成为可执行 JAR。

【讨论】:

【解决方案2】:

Tunaki 的回答是正确的,但在 Spring Boot 2 中不起作用。

Spring Boot 1.x

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

Read more


Spring Boot 2.x

如果您使用spring-boot-starter-parent,则repackage 目标会在ID 为repackage 的执行中自动执行。在该设置中,仅应指定配置,如下例所示:

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

Read more

【讨论】:

    【解决方案3】:

    对于 Spring Boot 2,@Tunaki 的答案必须根据 documentation 稍作修改,如果 spring-boot-starter-parent 用作父级:

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

    注意从spring-boot-starter-parent 覆盖执行所需的额外&lt;id&gt;repackage&lt;/id&gt;

    【讨论】:

      【解决方案4】:

      @Tunaki 所说的大部分是正确的,但根据您最初的问题,缺少的部分是:

      这会抛出 ClassNotFoundException。外部罐子用于 缺少 spring boot 应用程序。

      这是因为从 maven 打包创建的 FatJAR 具有在特定位置指定的依赖库,这些依赖库适用于 Spring Boot 如何执行应用程序。如果您只是将 JAR 添加到另一个应用程序的类路径中,那么您应该按照 @Tunaki 所说的去做,并将依赖的 JAR 文件包含到类路径中。解决此问题的最佳方法是使用专门针对 dependency:copy-dependencies mojo 的 Maven Dependency Plugin 将所有依赖项下载到一个文件夹中,然后您可以在编译其他应用程序时将其指定为库路径。

      【讨论】:

        【解决方案5】:

        您可以通过 maven-assembly-plugin 扩展您的项目

        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                </configuration>
                <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                    <goal>single</goal>
                    </goals>
                    </execution>
                </executions>
        </plugin>
        

        构建完成后,您将获得 3 个罐子。主要的项目与通常的 Maven 项目相同,而第二个项目的分类器将附加 exec 并且是可执行的 JAR。第三个 jar 名称将由 jar-with-dependencies 附加,并将包含您的类以及在您的 Spring Boot 应用程序中添加为依赖项的类(spring-boot-starter-web、thymeleaf、...),因此进入 pom您想要将该项目添加为依赖项的应用程序,您无需从 Spring Boot 项目添加依赖项。

        【讨论】:

          【解决方案6】:

          使用下面提供的构建部分,它将做三件事:

          1. 使用 spring-boot-maven-plugin 创建 spring boot jar
          2. 使用 maven-assembly-plugin 创建一个包含源代码编译类的普通 jar
          3. 将普通jar安装到本地m2文件夹中
          4. 如果要将普通jar部署到远程仓库,配置部署插件

            <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-assembly-plugin</artifactId>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>single</goal>
                                </goals>
                                <configuration>
                                    <appendAssemblyId>true</appendAssemblyId>
                                    <descriptors>
                                        <descriptor>src/main/resources/sources-jar-build.xml</descriptor>
                                    </descriptors>
                                    <finalName>${pom.artifactId}-${pom.version}</finalName>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-install-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>install-file</id>
                                <goals>
                                    <goal>install-file</goal>
                                </goals>
                                <configuration>
                                    <file>${pom.artifactId}-${pom.version}</file>
                                    <artifactId>${pom.artifactId}</artifactId>
                                    <groupId>${pom.groupId}</groupId>
                                    <version>${pom.version}</version>
                                </configuration>
                            </execution>
                        </executions>               
                    </plugin>
                </plugins>
            </build>
            


          将以下内容放在名为“sources-jar-build.xml”的文件中,放入资源文件夹:

          <assembly
              xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
              <id>sources</id>
              <includeBaseDirectory>false</includeBaseDirectory>
          
              <formats>
                  <format>jar</format>
              </formats>
              <fileSets>
                  <fileSet>
                      <directory>${project.basedir}/target/classes</directory>
                      <outputDirectory>/</outputDirectory>
                  </fileSet>
              </fileSets>
          </assembly>
          

          【讨论】:

            【解决方案7】:

            如果您想使用 spring-boot 项目作为依赖项,同时又想作为 spring-boot jar 运行,请使用以下配置。通过以下配置,您可以实现两个目标。

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

            此配置创建两个 jar,如下示例截图所示:

            【讨论】:

            • 这个答案非常好,我觉得它最好地回答了“如何配置我的构建以创建可执行 jar 和可以导入而不会导致 ClassNotFoundException 的依赖 jar”的问题跨度>
            【解决方案8】:

            将以下插件用于 Spring Boot 版本 2.*

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

            【讨论】:

              【解决方案9】:

              您可以设置您的项目,以便批处理启动器依赖一个 jar,该 jar 将与您的其他应用程序共享。

              根据您最初的要求,换一种说法:

              我想在我的其他应用程序中使用这个 Jar,所以将此 jar 添加到我的应用程序中。

              假设您的 jar 是您的项目 A,而您的应用程序是您的项目 B。

              现在,我的建议是从 A 中删除启动部分; 然后你把它放到一个新的项目 C 中,它会嵌入 Spring Boot,并且几乎完全依赖于 A。

              那么,由于 A 现在是一个简单的 jar,B 可以将其用作依赖项。

              【讨论】:

                【解决方案10】:

                我使用的是 2.2.5 版本,它可以正常工作。将其添加到您的 pom.xml

                <plugins>
                            <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                                <version>2.2.5.RELEASE</version>
                                <executions>
                                    <execution>
                                        <id>repackage</id>
                                        <configuration>
                                            <classifier>exec</classifier>
                                        </configuration>
                                    </execution>
                                </executions>
                            </plugin>
                        </plugins>
                

                【讨论】:

                  【解决方案11】:

                  如果您想添加任何项目作为依赖项,您需要该项目&lt;groupId&gt;&lt;artifactId&gt;&lt;version&gt;,通过这些详细信息,您可以将项目作为依赖项添加到另一个模块或应用程序中 例如:您的应用程序 pom 详细信息

                  <project 
                          <groupId>com.sample</groupId>
                          <artifactId>sampleapp</artifactId>
                          <version>1.0</version>
                          <packaging>jar</packaging>
                  </project>`
                  

                  您的依赖项如下所示

                   <dependency>
                   <groupId>com.sample</groupId>
                   <artifactId>sampleapp</artifactId>
                   <version>1.0</version>
                  </dependency>
                  

                  【讨论】:

                    猜你喜欢
                    • 2019-08-02
                    • 2021-07-23
                    相关资源
                    最近更新 更多