Maven技术问询:代码编译入Jar仍需指定classpath?关联空Jar Pom问题
咱们来拆解你遇到的这个问题:你已经把代码打包成Jar了,但运行时依然需要手动指定classpath,结合你提到这是承接之前《Maven:为何以下pom.xml生成空Jar包?》的问题,先看看你给出的pom.xml片段:
<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"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.earnix.eo</groupId> <artifactId>EOParent</artifactId> <version>8... </project>
核心原因主要集中在Maven默认的打包逻辑和你的配置细节上,具体来说:
1. 默认Jar只包含你的代码,不包含依赖
Maven的maven-jar-plugin默认行为很“克制”:它只会把你项目里编译好的class文件、资源文件打包进Jar,不会自动把你依赖的第三方库(比如Spring、Guava这些)也打包进去。
当你运行这个Jar时,JVM找不到这些依赖类,所以必须通过java -cp "你的Jar包路径:依赖Jar路径/*" 主类全路径这种方式,手动告诉JVM去哪里找这些依赖。
2. 你没配置“可执行Jar”的打包插件
如果想摆脱手动指定classpath的麻烦,你需要让Maven生成可执行Jar(也就是常说的“胖Jar”),这就得用到专门的插件:
maven-assembly-plugin:可以把所有依赖的类打包进同一个Jar,生成一个独立运行的包;maven-shade-plugin:功能类似,还能处理依赖冲突、重命名类等复杂场景。
比如给你一个maven-assembly-plugin的配置示例,你可以加到自己的pom.xml的<build><plugins>节点里:
<plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <configuration> <!-- 指定打包成包含所有依赖的Jar --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 配置主类,这样可以用java -jar直接运行 --> <archive> <manifest> <mainClass>你的主类全路径,比如com.earnix.eo.YourMainClass</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <!-- 绑定到package阶段,执行mvn package时自动生成胖Jar --> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
执行mvn package后,你会在target目录下看到两个Jar:一个是普通Jar,另一个带-jar-with-dependencies后缀的就是胖Jar,直接用java -jar 这个胖Jar的名字.jar就能运行,不用再指定classpath。
3. 之前空Jar问题的遗留影响
你提到之前遇到过生成空Jar的情况,大概率是当时的pom配置有问题(比如源码路径不对、编译插件配置错误)。虽然现在Jar不是空的,但打包逻辑可能依然不完整——父POM(你配置的EOParent)可能没有默认配置这些打包插件,导致你需要自己补充配置才能处理依赖打包。
内容的提问来源于stack exchange,提问作者CrazySynthax

