如何将依赖项添加到另一个项目中的 Spring Boot Jar?
How to add a dependency to a Spring Boot Jar in another project?
我有一个 Spring 引导应用程序,我已经从中创建了一个 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 引导 JAR 添加依赖项?
默认情况下,Spring Boot 将您的 JAR 重新打包为可执行 JAR,它通过将所有 类 放入 BOOT-INF/classes
以及所有依赖库来实现这一点BOOT-INF/lib
。创建这个胖 JAR 的后果是您不能再将它用作其他项目的依赖项。
来自Custom repackage classifier:
By default, the repackage
goal will replace the original artifact with the repackaged one. That's a sane behaviour for modules that represent an app but if your module is used as a dependency of another module, you need to provide a classifier for the repackaged one.
The reason for that is that application classes are packaged in BOOT-INF/classes
so that the dependent module cannot load a repackaged jar's classes.
如果想保留原来的主神器,以便作为依赖使用,可以在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:主要的一个与通常的 Maven 项目相同,而第二个将附加分类器并成为可执行 JAR .
@Tunaki 所说的大部分是正确的,但根据您的原始问题,缺少的部分是:
This throwing ClassNotFoundException. The External jar's used in
spring boot application is missing.
这是因为从 maven 打包创建的 FatJAR 在特定位置指定了依赖库,这些库适用于 Spring Boot 执行应用程序的方式。如果您只是将 JAR 添加到另一个应用程序的类路径中,那么您应该按照@Tunaki 所说的进行操作,并将依赖的 JAR 文件包含到类路径中。最好的方法是使用 Maven Dependency Plugin 专门针对 dependency:copy-dependencies
mojo 将所有依赖项下载到一个文件夹中,然后您可以在编译其他应用程序时将其指定为库路径。
您可以设置您的项目,以便批处理启动器依赖于一个 jar,该 jar 将与您的其他应用程序共享。
换句话说,根据您最初的要求:
I want to use this Jar in my other application so added this jar to my application.
假设您的 jar 是您的项目 A,您的应用程序是您的项目 B。
现在,我建议您从 A 中删除启动部分;
然后你把它放到一个新的项目 C 中,它将嵌入 Spring Boot,并且几乎完全依赖于 A.
然后,由于 A 现在是一个简单的 jar,B 可以将其用作依赖项。
您可以通过 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 启动应用程序中的依赖项(spring-boot-starter -web, thymeleaf,...), 所以进入你想将该项目添加为依赖项的应用程序的 pom 中,你不必从 spring 引导项目添加依赖项。
任何项目,如果您想添加为依赖项,您需要该项目 <groupId>
、<artifactId>
、<version>
,使用这些详细信息,您可以将项目添加为另一个模块中的依赖项或申请
例如:您的应用程序 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>
对于 Spring Boot 2 @Tunaki's answer 必须根据 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
覆盖执行所需的额外 <id>repackage</id>
。
Tunaki 的答案是正确的,但在 Spring Boot 2.
中不起作用
Spring开机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>
Spring开机2.x
If you are using spring-boot-starter-parent
, the repackage
goal is executed automatically in an execution with id repackage
. In that setup, only the configuration should be specified as shown in the following example:
<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>
使用下面提供的构建部分,它将做三件事:
- 使用 spring-boot-maven-plugin
创建 spring 引导 jar
- 用 类 使用 maven-assembly-plugin
编译的源代码创建一个普通的 jar
- 将普通jar安装到本地的m2文件夹中
如果要将普通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>
使用下面的插件 spring 启动版本 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>
如果你想使用 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,如下例截图所示:
我使用的是 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>
所有现有答案都是在假设另一个项目应该依赖的 Spring Boot 项目是一个应用程序的情况下做出的,这很公平,因为问题是这样表述的。
但是如果底层项目打算用作库仅,即它不包含(合理的)Main class,显然没有可执行代码需要重新打包。
所以在那种情况下,像这样完全跳过重新打包更有意义:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<b><skip>true</skip></b>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
我有一个 Spring 引导应用程序,我已经从中创建了一个 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 引导 JAR 添加依赖项?
默认情况下,Spring Boot 将您的 JAR 重新打包为可执行 JAR,它通过将所有 类 放入 BOOT-INF/classes
以及所有依赖库来实现这一点BOOT-INF/lib
。创建这个胖 JAR 的后果是您不能再将它用作其他项目的依赖项。
来自Custom repackage classifier:
By default, the
repackage
goal will replace the original artifact with the repackaged one. That's a sane behaviour for modules that represent an app but if your module is used as a dependency of another module, you need to provide a classifier for the repackaged one.The reason for that is that application classes are packaged in
BOOT-INF/classes
so that the dependent module cannot load a repackaged jar's classes.
如果想保留原来的主神器,以便作为依赖使用,可以在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:主要的一个与通常的 Maven 项目相同,而第二个将附加分类器并成为可执行 JAR .
@Tunaki 所说的大部分是正确的,但根据您的原始问题,缺少的部分是:
This throwing ClassNotFoundException. The External jar's used in spring boot application is missing.
这是因为从 maven 打包创建的 FatJAR 在特定位置指定了依赖库,这些库适用于 Spring Boot 执行应用程序的方式。如果您只是将 JAR 添加到另一个应用程序的类路径中,那么您应该按照@Tunaki 所说的进行操作,并将依赖的 JAR 文件包含到类路径中。最好的方法是使用 Maven Dependency Plugin 专门针对 dependency:copy-dependencies
mojo 将所有依赖项下载到一个文件夹中,然后您可以在编译其他应用程序时将其指定为库路径。
您可以设置您的项目,以便批处理启动器依赖于一个 jar,该 jar 将与您的其他应用程序共享。
换句话说,根据您最初的要求:
I want to use this Jar in my other application so added this jar to my application.
假设您的 jar 是您的项目 A,您的应用程序是您的项目 B。
现在,我建议您从 A 中删除启动部分; 然后你把它放到一个新的项目 C 中,它将嵌入 Spring Boot,并且几乎完全依赖于 A.
然后,由于 A 现在是一个简单的 jar,B 可以将其用作依赖项。
您可以通过 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 启动应用程序中的依赖项(spring-boot-starter -web, thymeleaf,...), 所以进入你想将该项目添加为依赖项的应用程序的 pom 中,你不必从 spring 引导项目添加依赖项。
任何项目,如果您想添加为依赖项,您需要该项目 <groupId>
、<artifactId>
、<version>
,使用这些详细信息,您可以将项目添加为另一个模块中的依赖项或申请
例如:您的应用程序 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>
对于 Spring Boot 2 @Tunaki's answer 必须根据 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
覆盖执行所需的额外 <id>repackage</id>
。
Tunaki 的答案是正确的,但在 Spring Boot 2.
中不起作用Spring开机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>
Spring开机2.x
If you are using
spring-boot-starter-parent
, therepackage
goal is executed automatically in an execution with idrepackage
. In that setup, only the configuration should be specified as shown in the following example:
<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>
使用下面提供的构建部分,它将做三件事:
- 使用 spring-boot-maven-plugin 创建 spring 引导 jar
- 用 类 使用 maven-assembly-plugin 编译的源代码创建一个普通的 jar
- 将普通jar安装到本地的m2文件夹中
如果要将普通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>
使用下面的插件 spring 启动版本 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>
如果你想使用 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,如下例截图所示:
我使用的是 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>
所有现有答案都是在假设另一个项目应该依赖的 Spring Boot 项目是一个应用程序的情况下做出的,这很公平,因为问题是这样表述的。
但是如果底层项目打算用作库仅,即它不包含(合理的)Main class,显然没有可执行代码需要重新打包。
所以在那种情况下,像这样完全跳过重新打包更有意义:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<b><skip>true</skip></b>
</configuration>
</execution>
</executions>
</plugin>
</plugins>