java - 为什么 javac -proc :only option still parse java files when class files already exist?

标签 java annotations javac

我有一个很大的java项目,需要单独进行注解处理来编译代码。

所以我考虑使用javac编译器的-proc选项,如下所示:

  1. javac -proc:none ... -- 生成类文件。

  2. javac -proc:only -processor x.y.z.MyAnnotationProcessor ... -- 检查上一步中生成的类文件并生成代码。

但似乎 javac -proc:only 选项仍然解析 .java 文件:

$ javac -proc:only -processor x.y.z.MyAnnotationProcessor ... 
[parsing started RegularFileObject[Foo.java]]
[parsing completed 14ms]
[search path for source files: target\classes]
[search path for class files: ... ]
...
Round 1:
    input files: {Foo}
    annotations: []
    last round: false

我本以为,因为 Foo.class 文件存在于 targets/classes 中,并且其时间戳晚于相应的 Foo.java> 文件,那么就不需要解析源文件了? javac 是否真的从磁盘加载文件、解析它并在内存中构造类模型,而不实际将类模型写入文件?或者解析消息是否与从磁盘加载类文件有关?

这对我来说是一个问题,因为我有一个包含数千个 .java 文件的源代码树,并且解析这些文件两次(一次用于 -proc:none 一次用于 proc:only 调用)需要很长时间。

有没有一种方法可以运行注释处理器,以便它使用之前的 javac -proc:none 执行生成的类文件,而无需(显然)再次解析相同的源文件?

注意:我使用的是 JDK 1.7.0_45。

编辑#1

更多细节:

javac -proc:none 命令和输出:

C:\foo> javac -proc:none -verbose src\main\java\x\y\z\*.java
[parsing started RegularFileObject[src\main\java\x\y\z\Bar.java]]
[parsing completed 15ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Baz.java]]
[parsing completed 0ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Foo.java]]
[parsing completed 1ms]
[search path for source files: .]
[search path for class files: C:\Program Files\Java\jdk1.7.0_45\jre\lib\resources.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\rt.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jce.jar,C:\Program    Files\Java\jdk1.7.0_45\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jfr.jar,C:\Program Files\Java\jdk1.7.0_45\jre\classes,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\access-bridge-64.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\jaccess.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunec.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\zipfs.jar,.]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Deprecated.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Retention.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/RetentionPolicy.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Target.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/ElementType.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Annotation.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/AutoCloseable.class)]]
[wrote RegularFileObject[src\main\java\x\y\z\Bar.class]]
[checking x.y.z.Baz]
[wrote RegularFileObject[src\main\java\x\y\z\Baz.class]]
[checking x.y.z.Foo]
[wrote RegularFileObject[src\main\java\x\y\z\Foo.class]]
[total 271ms]

javac -proc:only 命令和输出:

C:\foo>javac -processorpath processor.jar -proc:only -processor x.y.z.MyAnnotationProcessor -verbose src\main\java\x\y\z\*.java
[parsing started RegularFileObject[src\main\java\x\y\z\Bar.java]]
[parsing completed 13ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Baz.java]]
[parsing completed 1ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Foo.java]]
[parsing completed 1ms]
[search path for source files: .]
[search path for class files: C:\Program Files\Java\jdk1.7.0_45\jre\lib\resources.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\rt.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jce.jar,C:\Program    Files\Java\jdk1.7.0_45\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\jfr.jar,C:\Program Files\Java\jdk1.7.0_45\jre\classes,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\access-bridge-64.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\jaccess.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunec.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.7.0_45\jre\lib\ext\zipfs.jar,.]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Deprecated.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Retention.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/RetentionPolicy.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Target.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/ElementType.class)]]
[loading ZipFileIndexFileObject[C:\Program Files\Java\jdk1.7.0_45\lib\ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Annotation.class)]]
Round 1:
    input files: {x.y.z.Bar, x.y.z.Baz, x.y.z.Foo}
    annotations: [java.lang.Deprecated]
    last round: false

我还尝试添加 -classpath src\main\java\x\y\z-implicit:none 选项,但 java 文件仍然被解析。

编辑#2

按照建议使用 -sourcepath src\main\java\-cp src\main\java\ 选项:

C:\foo>javac -processorpath processor.jar -proc:only -processor x.y.z.MyAnnotationProcessor -verbose -sourcepath src\main\java -cp src\main\java src\main\java\x\y\z\*.java
[parsing started RegularFileObject[src\main\java\x\y\z\Bar.java]]
[parsing completed 14ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Baz.java]]
[parsing completed 0ms]
[parsing started RegularFileObject[src\main\java\x\y\z\Foo.java]]
[parsing completed 0ms]
[search path for source files: src\main\java]
[search path for class files: C:\Program Files\Java\jdk1.7.0_45\jre\lib\resources.jar, ... etc ..., src\main\java ]

我在编辑#1中使用了错误的-sourcepath设置,但按照建议使用了正确的-sourcepath,我观察到源文件仍然被加载和解析。

我没有看到在不指定 java 源文件的情况下调用 javac 的方法,因此它们将始终被加载和解析。也许javac -proc:only选项可以理解为“java文件将被加载并解析并执行注释处理,但解析后的java文件对应的类文件不会写入磁盘“

最佳答案

告诉它处理.java 文件,因此它处理.java 文件。你期待什么?您在命令行中将它们命名为:src\main\java\x\y\z\*.java。您可以告诉它处理 .class 文件,如果您希望它这样做的话,或混合物。

注意还有一些其他问题,这些问题适用于 -proc:none-proc:only。

javac -processorpath processor.jar -proc:only -processor x.y.z.MyAnnotationProcessor -verbose src\main\java\x\y\z\*.java

应该是这样

javac -processorpath processor.jar -proc:only -processor x.y.z.MyAnnotationProcessor -verbose -sourcepath src\main\java -cp src\main\java src\main\java\x\y\z\*.java

或者,更好的是,从 src\main\java 目录中执行命令并省略 -sourcepath-cp 参数。如果您在编译时指定了 -d 选项(-proc:none),则在执行时应在 -cp 选项中指定相同的目录-proc:only.

关于java - 为什么 javac -proc :only option still parse java files when class files already exist?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26170781/

相关文章:

java - 是否可以在jtable中编辑数据并保存?

java - org.hibernate.exception.GenericJDBCException : could not insert:

java - Ant:如果类路径 jar 已更改但源代码未更改,如何强制进行 java 编译

java - 弹出 ="true"无法在 JSF 2.0 环境的 Spring webflow 2.3.0 中使用

java - 如何从jspinner获取日期值

java - 在列表中查找注释

java - 如何在 Go 中使用/实现切面方向?

java - @Override 不强制在重写方法中使用枚举注释

Javac 在 ant build 中不起作用

Javac:选项编译没有注释