问题描述
在开发过程中,有个业务需求,需要增加redis缓存。为了图省事,后续可以重复利用,于是写了一个子项目(项目B),项目B主要封装redis相关操作。其他项目如果想要使用redis,直接依赖包即可。开开心心把代码写好,然后另外一个项目(项目A)也引入了项目B的依赖。写完代码后,然后需要打包成jar包发布到服务器上,然后用maven编译A项目就一直报错,报某个class没有找到。编译B项目时正常,且可以安装到本地maven仓库里。在仓库里项目B的jar包中,也找到相关的class文件。项目结构如下:
总项目
----项目A
----项目B
总项目的pom.xml文件类似如下
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>project-a</module>
<module>project-b</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<groupId>com.test</groupId>
<artifactId>project-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-root</name>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<lombok-version>1.18.24</lombok-version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
项目B的pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.test</groupId>
<artifactId>project-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.test</groupId>
<artifactId>project-b</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-b</name>
<properties>
...
</properties>
<dependencies>
...
</dependencies>
</project>
项目A的pom.xml类似如下
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.test</groupId>
<artifactId>project-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.test</groupId>
<artifactId>project-a</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-a</name>
<properties>
...
</properties>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>project-b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
...
</dependencies>
</project>
解决方法
移除掉根项目pom.xmk中的
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
A项目中的pom.xml中增加上面的build。
原因分析
spring-boot-maven-plugin 是用来打包可执行jar包的,普通jar不需要这个,使用默认的maven-jar-plugin 就好。
可执行jar包和普通jar包的区别
| 特性 | 可执行 JAR(Spring Boot 打包) | 普通 JAR(标准 Maven 打包) |
|---|---|---|
| 用途 | 用于独立运行 java -jar app.jar | 用于作为依赖库被其他项目引用 |
| 结构 | 类在 BOOT-INF/classes/,依赖在 BOOT-INF/lib/ | 类直接在根目录下,如 com/xxx/YourClass.class |
| 是否包含依赖 | ✅ 包含所有依赖(fat jar) | ❌ 只包含自己的代码 |
| 能否被其他项目依赖? | ❌ 不推荐! 编译时找不到类 | ✅ 可以正常被依赖 |
| 打包插件 | spring-boot-maven-plugin | maven-jar-plugin(默认) |
还是maven基本功不行。
希望能帮到遇到同样问题的小伙伴。