我有一个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添加依赖项?
答案 0 :(得分:89)
默认情况下,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:主要的一个将与通常的Maven项目相同,而第二个将附加分类器并且是可执行的JAR。
答案 1 :(得分:2)
@Tunaki所说的大部分都是正确的,但根据您原来的问题,缺少的部分是:
抛出ClassNotFoundException。外部罐子用于 春季启动应用程序丢失了。
这是因为从maven包装创建的FatJAR具有在特定位置指定的依赖库,这些库适用于Spring Boot如何执行应用程序。如果您只是将JAR添加到另一个应用程序的类路径中,那么您应该执行@Tunaki所说的内容,并将依赖的JAR文件包含到类路径中。处理此问题的最佳方法是使用专门针对dependency:copy-dependencies
mojo的Maven Dependency Plugin将所有依赖项下载到一个文件夹中,然后在编译其他应用程序时将其指定为库路径。
答案 2 :(得分:2)
您可以通过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 boot项目添加依赖项。
答案 3 :(得分:1)
在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>
答案 4 :(得分:1)
如果你想使用 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,如下面的示例截图所示:
答案 5 :(得分:0)
您可以设置项目,以便批处理启动程序依赖于jar,该jar将与您的其他应用程序共享。
根据您的初始请求说明不同:
我想在我的其他应用程序中使用这个Jar,所以将这个jar添加到我的应用程序中。
假设你的jar是你的项目A,你的应用程序就是你的项目B.
现在,我建议你从A中移除发射部分; 然后你把它放到一个新的项目C中,它将嵌入Spring Boot,而这几乎完全依赖于A.
然后,由于A现在是一个简单的jar,B可以将它用作依赖。
答案 6 :(得分:0)
对于Spring Boot 2,如果将spring-boot-starter-parent
用作父级,则必须根据documentation来修改@Tunaki的答案:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
不要带走从<id>repackage</id>
覆盖执行所需的多余spring-boot-starter-parent
。
答案 7 :(得分:0)
Tunaki的答案是正确的,但在 Spring Boot 2 中不起作用。
<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-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>
答案 8 :(得分:0)
使用下面提供的构建部分,它将做三件事:
如果要将普通的jar部署到远程存储库中,请配置deploy插件
<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>
答案 9 :(得分:-1)
任何项目,如果要添加为依赖项,则需要该项目<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>