我们以注释javac
的形式为Processor
编译器实现了一些metamagic。有了一些看似无辜的java源文件,我们得到以下矛盾的错误信息:
[javac] [checking org.dirty_ice.underscores.tower_defense.wave.HumanSpawner]
[javac] /home/kris/bme/tower_defense/src/game/org/dirty_ice/underscores/tower_defense/wave/HumanSpawner.java:9: cannot find symbol
[javac] symbol: class java
[javac] @Trace("spawner")
[javac] ^
@Trace是我们正在尝试处理的注释的名称,但是错误发生在其他一些类中,其中行号与正在处理的注释无关。注释处理器将TreeTranslator
应用于带注释的类的AST,从而重写AST本身。
如果我们直接调用ant
或javac
,则错误消失了程序,注释处理器似乎在Linux下正常运行。在Windows下,第二次编译没有帮助,我们再次收到错误。当然,如果我们ant clean
或手动删除输出目录,即使在Linux上也会再次抛出错误。
JDK 1.7和1.6同时出现以下错误消息(注释处理器正在使用相应的tools.jar进行编译)。
似乎javac的类文件检查器认为java
是类,绝对不是。我们项目的课程路径中根本没有这样的课程名称,我们无处可依赖。不幸的是,在检查失败后,类没有写入文件系统,因此我们可以检查 - 可能是严重受损的类文件。
什么可能导致这样令人费解的编译错误?有没有办法在编译后检查失败的类文件并解开这个谜团?
我们设法将问题缩小到以下几个方面:
有一个类,比如Wtf
,它包含一个切换枚举的switch语句(参见https://stackoverflow.com/a/4319152/560450)或其他一些匿名内部类。如果类{,1}},AA
,BB
和CC
继承自DD
且包含至少一种方法(Wtf
似乎跳过检查空类),注释处理器生成的AST部分包含对来自javac
,java.lang.Object
,java.lang
和{{的其他内容的BB
的引用1}},即所有后代,但按字典顺序首先会产生错误。原因可能是CC
内的一些竞争条件与加载内部类和解析对DD
的引用有关,或者其他一些曲折的小方法调用都是相似的。