Maven Shaded Jar中Salesforce API类出现NoClassDefFoundError问题
我之前也碰到过一模一样的情况——IDE里跑的好好的,打包成shaded jar就报NoClassDefFoundError,核心原因就是你的shaded jar没把Salesforce的依赖包正确打包进去,或者依赖的scope配置不对导致插件跳过了它。下面给你一步步排查和解决的方法:
1. 先检查依赖的Scope配置
打开你的pom.xml,找到com.sforce相关的依赖(比如force-wsc),看看是不是加了<scope>provided</scope>:
<dependency> <groupId>com.force.api</groupId> <artifactId>force-wsc</artifactId> <version>xxx</version> <!-- 如果有这行,赶紧注释掉或者删掉! --> <!-- <scope>provided</scope> --> </dependency>
provided意味着这个依赖是由运行环境提供的(比如容器),Maven打包时会自动跳过它。IntelliJ里能运行是因为IDE会把所有依赖(哪怕是provided)都加到运行类路径里,但shaded jar不会包含这些依赖,所以命令行跑就找不到类了。
2. 配置正确的Maven Shade插件
确保你的shade插件配置包含了必要的transformer,尤其是处理服务文件和主类的部分——Salesforce的WSC依赖用到了META-INF/services里的配置文件,不处理的话会被覆盖,也可能导致类加载失败。
把下面的配置加到pom.xml的<build><plugins>里:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <!-- 建议用最新稳定版 --> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <!-- 指定你的主类,这样可以直接用java -jar运行 --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.yourpackage.YourMainClass</mainClass> </transformer> <!-- 合并META-INF/services里的文件,避免Salesforce的服务配置被覆盖 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <!-- 可选:排除签名文件,避免打包时的警告 --> <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>
3. 验证打包结果
运行mvn clean package重新打包,然后到target目录下找到带-jar-with-dependencies后缀的shaded jar(这是shade插件生成的包含所有依赖的jar)。
你可以用下面的命令检查EnterpriseConnection类是否已经被打包进去:
jar tf target/your-project-name-jar-with-dependencies.jar | grep com/sforce/soap/enterprise/EnterpriseConnection
如果输出了类的路径,说明已经打包成功了,再用java -jar target/your-project-name-jar-with-dependencies.jar运行应该就没问题了。
4. 额外排查:依赖冲突
如果上面的步骤都做了还是报错,那可能是依赖冲突导致的。运行mvn dependency:tree查看依赖树,看看是不是有多个版本的force-wsc或者相关依赖,找到冲突的版本并排除掉即可。
内容的提问来源于stack exchange,提问作者rbuzby

