JAR包内class文件被忽略 仅classpath含目录时可加载类
问题根因
JAR包内的class文件路径层级错误,不符合Java类加载的路径匹配规则。
Java的类加载器查找类时严格和包名对齐:test.Main类要求classpath下必须存在直接对应包路径的test/Main.class文件,不会递归扫描JAR内的多层子目录找class。你当前打出的JAR里class文件存放在out/test/Main.class路径,多套了一层out/前缀,类加载器自然识别不到。
现象验证
你之前同时把JAR和out目录加入classpath能正常运行,本质是JVM直接从out目录下读到了正确路径的test/Main.class,和JAR包内的文件没有任何关系——这也是为什么删掉/重命名out目录下的class文件就立刻报错的原因。
解决方案(无需自定义manifest)
核心是打包时不要把out这层编译输出目录打进JAR,保证class文件在JAR内的路径和包名完全对应,两种方式都可以:
- 方式1:切换到编译输出目录后再打包
依次执行以下命令:cd out jar -cvf ..\mods\un.jar test\Main.class - 方式2:直接在项目根目录用
-C参数指定打包时的基准目录,不用切换路径:jar -cvf mods\un.jar -C out test\Main.class
打包完成后可以检查JAR内部结构,正确的文件列表应该是:
META-INF\MANIFEST.MF test\Main.class
此时直接执行java -cp mods\un.jar test.Main即可正常运行,输出Unnamed module...。
打包逻辑说明
你之前执行的jar -cvf mods\un.jar out\test\Main.class命令,会把你传入的文件路径原封不动写入压缩包,所以才会带上多余的out/目录层级。-C参数的作用就是告诉jar命令先进入指定的out目录,再把后续传入的test\Main.class按相对路径写入JAR,刚好匹配包名对应的目录结构。
内容的提问来源于stack exchange,提问作者Sean Kennedy
相关产品推荐
相关产品推荐

