JDK7+ javah工具依赖文件修改时间的异常行为及原因问询
问题背景
- 目录结构:根目录下的
Class_B.java继承子目录subdir中的Class_A.java - 编译后生成
./Class_B.class和subdir/Class_A.class - JDK6下
javah执行正常;但JDK7+中,只要Class_B.class的修改时间比Class_B.java晚,javah就会报错找不到Class_A;但用touch Class_B.java更新源文件的修改时间后,javah又能正常工作。
行为变更的核心原因
JDK7彻底调整了javah的处理优先级逻辑:
- JDK6时期:
javah默认优先处理Java源文件,不管对应class文件是否存在、是否更新。它会直接解析源文件中的继承依赖关系,自动识别子目录中的依赖源文件(比如subdir/Class_A.java),无需依赖已编译的class文件即可完成头文件生成。 - JDK7+时期:
javah新增了"文件更新时间优先"的判断逻辑:如果目标类的class文件修改时间晚于源文件,就直接加载class文件进行处理。此时工具会严格遵循标准类加载规则查找依赖类——即Class_A.class必须在类路径(classpath)中可被定位。如果未显式指定-classpath .,JDK7+的javah可能未将当前目录默认纳入类路径范围,导致无法找到subdir/Class_A.class;而当touch更新源文件时间后,源文件时间晚于class文件,javah会回退到处理源文件的模式,此时它会自动解析源文件的依赖路径,因此能正常找到Class_A。
官方文档依据
JDK7的工具更新文档中明确记录了该变更:
javah工具现在会优先使用更新的class文件(当class文件比对应源文件新时),而非默认处理源文件。当基于class文件处理时,工具会遵循标准类路径规则解析依赖类,若依赖类不在类路径中,会抛出类找不到的错误。
此外,JDK7的javah手册补充说明:如果指定的是类名而非源文件名,工具会在类路径中搜索class文件;若想强制让它处理源文件,可以使用-jni参数(该参数在JDK7中仍有效,JDK8之后被标记为过时)。
内容的提问来源于stack exchange,提问作者Alexander Samoylov
相关产品推荐
相关产品推荐

