为什么当类文件已存在时,javac -proc:only选项仍会解析java文件?

时间:2014-10-02 22:41:38

标签: java annotations javac

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

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

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

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

  3. 但似乎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>

1 个答案:

答案 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选项中指定相同的目录。