我有一个大的java项目,需要单独执行注释处理来编译代码。
所以我考虑使用-proc
编译器的javac
选项,如下所示:
javac -proc:none ...
- 生成类文件。
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文件的相应类文件不会写入磁盘”?< / p>
答案 0 :(得分:0)
你告诉它处理.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
选项中指定相同的目录。