Maven打包带依赖的SDK Jar:Idea依赖展示及依赖加载问题求助
解决方案:打包可作为普通Jar使用的Spring Boot SDK
核心问题分析
之前的尝试踩了两个关键坑:
spring-boot-maven-plugin生成的是Spring Boot特有的可执行Fat Jar,类文件存放在BOOT-INF/classes下,依赖包在BOOT-INF/lib,普通项目无法按标准Jar规则加载类。maven-assembly-plugin的jar-with-dependencies预定义描述符会把所有依赖类平铺到Jar根目录,既会导致类名冲突,又会丢失依赖元数据,导致IDEA无法解析依赖树,同时类加载时易出现FileNotFound异常。
下面给出两种适配场景的方案:
方案一:标准Maven SDK打包(推荐)
和org.apache.commons、poi的打包逻辑一致,SDK Jar仅包含自身代码,依赖通过Maven的依赖传递机制管理,天然支持IDEA依赖树展示,且不会出现依赖加载问题。
配置示例
<build> <plugins> <!-- 禁用Spring Boot的可执行Jar打包,仅保留编译支持 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> <configuration> <!-- 生成单独的可执行Jar(带exec后缀),不影响普通SDK Jar --> <classifier>exec</classifier> </configuration> </execution> </executions> </plugin> <!-- 配置普通Jar打包,仅包含自身类 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>${maven-jar-plugin.version}</version> <configuration> <archive> <manifest> <!-- 无mainClass,符合SDK定位 --> <mainClass>none</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build>
效果说明
- 打包后生成两个Jar:带
-exec后缀的是可执行Fat Jar,不带后缀的是普通SDK Jar。 - 其他项目引入SDK时,Maven会自动拉取
pom.xml中声明的第三方依赖,IDEA可直接展示完整依赖树。 - 类加载完全遵循标准Jar规则,不会出现
FileNotFound异常。
方案二:打包包含依赖的Fat Jar(特殊场景需求)
如果必须将第三方依赖打包进SDK Jar(比如离线环境),不要用jar-with-dependencies,改用maven-shade-plugin,它能处理类冲突并保留依赖元数据。
配置示例
<build> <plugins> <!-- 同样禁用Spring Boot默认的可执行Jar打包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> <configuration> <classifier>exec</classifier> </configuration> </execution> </executions> </plugin> <!-- 使用shade插件打包带依赖的Jar --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${maven-shade-plugin.version}</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <!-- 生成精简Pom,避免重复依赖 --> <createDependencyReducedPom>true</createDependencyReducedPom> <!-- 重定位依赖包路径,避免类名冲突 --> <relocations> <relocation> <pattern>org.apache.commons</pattern> <shadedPattern>com.yourcompany.sdk.shaded.org.apache.commons</shadedPattern> </relocation> <!-- 其他第三方依赖包可按需添加重定位规则 --> </relocations> <!-- 排除签名文件,避免Jar验证失败 --> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> </plugins> </build>
效果说明
- 打包后的Jar包含自身类和第三方依赖类,且通过重定位避免类冲突。
createDependencyReducedPom会生成精简Pom,确保其他项目引入时不会重复加载已打包的依赖。- IDEA可通过Pom解析依赖树,类加载路径正常,不会抛出
FileNotFound异常。
额外注意事项
- 发布SDK到Maven仓库时,必须同时上传Jar和
pom.xml,否则依赖传递失效。 - 合理设置依赖的
scope:比如SDK依赖的spring-boot-starter-web若不是必要功能,可设为provided,由使用方自行决定是否引入。 - 测试时,在IDEA中查看
Project Structure -> Libraries,确认依赖树是否正确展示,同时编写测试代码验证SDK功能是否正常运行。
内容的提问来源于stack exchange,提问作者EricLin
相关产品推荐
相关产品推荐

