使用javac编译依赖自定义Jar包时出现包不存在错误的求助
编译依赖自定义Jar包的Java文件时出现包找不到错误
目录结构
compile_java ├── my_lib │ ├── bin │ │ ├── pak1 │ │ │ └── A.class │ │ └── pak2 │ │ └── B.class │ ├── dist │ │ └── my_lib.jar │ └── src │ ├── pak1 │ │ └── A.java │ └── pak2 │ └── B.java └── using_lib ├── bin └── src └── main └── Main.java
源代码
A.java
package pak1; public class A { public void method(){ System.out.println("A method executed"); } }
Main.java
package main; import pak1.*; import pak2.*; public class Main { public static void main(String[] args) { A a = new A(); a.method(); B b = new B(); b.method(); } }
执行的命令及错误
生成Jar包的命令
compile_java$ jar cvf my_lib/dist/my_lib.jar my_lib/bin/pak1/A.class my_lib/bin/pak2/B.class
编译Main.java的命令
javac -d using_lib/bin/ -cp my_lib/dist/*.jar using_lib/src/main/Main.java
报错信息
using_lib/src/main/Main.java:3: error: package pak1 does not exist import pak1.*; ^ using_lib/src/main/Main.java:4: error: package pak2 does not exist import pak2.*; ^ using_lib/src/main/Main.java:7: error: cannot find symbol A a = new A(); ^ symbol: class A location: class Main using_lib/src/main/Main.java:7: error: cannot find symbol A a = new A(); ^ symbol: class A location: class Main using_lib/src/main/Main.java:10: error: cannot find symbol B b = new B(); ^ symbol: class B location: class Main using_lib/src/main/Main.java:10: error: cannot find symbol B b = new B(); ^ symbol: class B location: class Main 6 errors
问题原因
生成Jar包时,你把带前缀的相对路径my_lib/bin/pak1/A.class打包进了Jar,导致Jar内部的目录结构是my_lib/bin/pak1/A.class,而非Java类加载机制要求的、直接以pak1作为根目录下的包结构。编译器从类路径根目录查找对应包的class文件时,自然找不到正确的pak1、pak2包。
解决方法
方法一:修正Jar包打包命令(推荐)
两种方式可以确保Jar包内的包结构正确:
- 切换到
my_lib/bin目录后打包:
compile_java$ cd my_lib/bin my_lib/bin$ jar cvf ../dist/my_lib.jar pak1 pak2
- 不切换目录,用
-C参数指定打包根目录:
compile_java$ jar cvf my_lib/dist/my_lib.jar -C my_lib/bin pak1 pak2
-C参数会临时切换到指定目录,打包该目录下的内容,最终Jar内会直接包含pak1/和pak2/目录,符合Java类加载的路径要求。
方法二:临时修正编译类路径(仅测试用)
如果不想重新打包,可以把my_lib/bin也加入编译类路径,让编译器直接找到正确的class文件:
javac -d using_lib/bin/ -cp "my_lib/dist/my_lib.jar:my_lib/bin" using_lib/src/main/Main.java
但这种方法治标不治本,建议优先使用方法一修复Jar包结构。
验证修复效果
重新打包后,执行原编译命令即可正常编译:
javac -d using_lib/bin/ -cp my_lib/dist/my_lib.jar using_lib/src/main/Main.java
运行Main类:
java -cp "using_lib/bin:my_lib/dist/my_lib.jar" main.Main
会输出:
A method executed A method executed
内容的提问来源于stack exchange,提问作者castle shin
相关产品推荐
相关产品推荐

