当类文件已经存在时,为什么javac-proc:only选项仍然解析java文件?
我有一个大型java项目,需要单独执行注释处理来编译代码 因此,我考虑使用当类文件已经存在时,为什么javac-proc:only选项仍然解析java文件?,java,annotations,javac,Java,Annotations,Javac,我有一个大型java项目,需要单独执行注释处理来编译代码 因此,我考虑使用javac编译器的-proc选项,如下所示: javac-proc:none…——生成类文件 javac-proc:only-processor x.y.z.MyAnnotationProcessor…——检查在上一步中生成的类文件并生成代码 但是,javac-proc:only选项仍然解析.java文件: $ javac -proc:only -processor x.y.z.MyAnnotationProcessor
javac
编译器的-proc
选项,如下所示:
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文件存在于目标/类中,并且在相应的Foo.java文件之后有一个时间戳,那么解析源文件就没有必要了?javac是否真的从磁盘加载文件、解析文件并在内存中构建类模型,而不实际将类模型写入文件?或者解析消息是否与从磁盘加载类文件有关
这对我来说是个问题的原因是,我有一个包含数千个.java文件的源代码树,解析这些文件两次(一次用于-proc:none
,一次用于proc:only
调用)需要很长时间
是否有一种运行注释处理器的方法,以便它使用从先前的javac-proc:none
执行中生成的类文件,而不(显然)再次解析相同的源文件
注意:我使用的是JDK1.7.045
编辑#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]
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
javac-proc:only
命令和输出:
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]
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
),那么在执行-proc:only时,您应该在-cp
选项中指定相同的目录,我想看看javac命令的“…”中有什么内容。“源文件搜索路径”跟踪表明您搞错了。它不应该包括target\classes
,应该包括“类文件的搜索路径”。我在“编辑#1”中添加了更多细节,反映了一个更简单的过程。希望有帮助!这是毫无意义的,而你继续张贴。。。而不是实际的信息。道歉。我添加了缺少的输出(包括加载JDK jar、解压缩jar等)。希望能有帮助。谢谢你的建议。我最初尝试了“-sourcepath”,但错误地将其设置为“src\main\java\x\y\z”。我尝试按照建议将其设置为“src\main\java”,但输出仍然显示java源文件的加载和解析(请参见原始问题中的编辑#2)。因此,三个已处理的文件中哪一个不应该被解析,为什么不呢?它们都没有。类文件已存在,它们比源文件更新。我想知道是否有一种方法可以在编译时单独运行注释处理器,以便注释处理可以加载以前生成的类文件,而不是再次解析源代码。也许javac在这方面是错误的工具,但我正在使用的maven插件最终将委托给它。。。我所针对的注释具有COMPILE的保留策略,这意味着它将从类文件中剥离。因此,将类文件加载到注释处理器是行不通的。我不会将javac执行分为proc:none和proc:only,而是尝试在一个步骤中进行处理(这可能会导致一些其他问题,因为我生成的测试代码不是正常编译步骤的一部分)。但是您在命令行中将它们命名为:src\main\java\x\y\z\*.java
。您让它处理.java文件,所以它处理.java文件。你期待什么?您可以告诉它处理.class文件,如果您希望它这样做,或者混合使用。