Fat Jar与普通Jar的依赖解析及类路径技术问询
普通Jar与Fat Jar的依赖及类路径问题解析
一、Jar依赖使用疑问解答
1. 普通Jar的依赖处理
普通Jar仅包含库A自身的代码,不会打包其依赖X、Y、Z。服务B只引入A的普通Jar时:
- 编译阶段:如果代码调用A中不涉及X/Y/Z的方法,编译可以通过;但如果调用的A方法内部依赖了X/Y/Z,编译时就会直接报错(因为编译类路径里找不到这些依赖类)。
- 运行阶段:就算编译侥幸通过(比如A的方法用了反射加载依赖类),运行时调用到依赖X/Y/Z的逻辑时,会抛出
ClassNotFoundException或NoClassDefFoundError。
正确结论是:必须手动导入X、Y、Z,才能让A的所有功能正常工作,不是等调用到X/Y/Z方法时才需要导入——编译阶段就可能出问题,你的原理解存在偏差。
2. Fat Jar的依赖处理
Fat Jar已经将A和它的所有依赖X、Y、Z的字节码全部嵌入其中。服务B引入这个Fat Jar后,无需添加任何额外依赖,就能正常使用A的所有功能,甚至可以直接调用X/Y/Z的public方法(只要这些类的访问权限允许)。你的这个理解完全正确。
二、编译/运行类路径疑问解答
1. 引入普通Jar时的类路径
- 编译类路径:默认情况下仅包含A的普通Jar,X、Y、Z不在其中。如果服务B没手动引入X/Y/Z,编译时涉及依赖的代码会报错。
- 运行类路径:如果没手动导入X/Y/Z,运行类路径也只有A;只有当手动添加了X/Y/Z的依赖后,运行类路径才会包含A、X、Y、Z。你的原说法不准确,运行类路径是否包含依赖取决于是否手动引入。
2. 引入Fat Jar时的类路径
编译类路径和运行类路径都会包含Fat Jar中的所有类——也就是A、X、Y、Z。因为Fat Jar已经把所有依赖打包进去,不管编译还是运行,JVM都能从这个Jar里找到所有需要的类。你的这个理解是正确的。
内容的提问来源于stack exchange,提问作者Stefan Ss
相关产品推荐
相关产品推荐

