我编写了一个简单的Java注释处理器,该处理器生成一个Java文件和一个资源文件。

我已经将注释处理器打包到jar文件中,并且我的maven项目可以在maven生命周期的编译阶段加载它并处理注释。生成的代码按预期显示在目标/生成的源/注释中,生成的资源文件显示在目标/类中。

但是我只想在测试过程中使用生成的java文件和资源文件,因此我希望生成的文件分别出现在target / generated-test-sources / test-annotations和target / test-classes中。简而言之,我需要注释处理发生在测试-编译阶段,而不是编译阶段。

更重要的是:注释处理器运行生产代码,但生成的文件随后包含在target \ foo-test.jar中,而不是target \ foo.jar中。

我不确定如何使用Maven进行此操作,除了可能在 process-test-resources 阶段移动生成的文件外,这似乎很丑陋。

有什么建议么?

编辑:我尝试将<scope>test</scope>添加到注释处理器的依赖项中,我可以看到该处理器是在 testCompile 阶段创建的,但是未调用该处理器的process()方法,并且什么也没有发生。

编辑#1 :注释处理器包含以下代码,用于在META-INF / services下写入.java文件和resouce文件:

@Override 
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
  List<String> declarations = generateDeclarationsForAnnotation(roundEnv); 
  generateServiceImplFile(declarations); 
  generateResourceFile(); 
  return true; 
} 
 
private void generateResourceFile() throws Exception { 
  JavaFileManager.Location location = StandardLocation.CLASS_OUTPUT; 
  FileObject file= processingEnv.getFiler().createResource(location, 
    "", "META-INF/services/x.y.z.FooService"); 
  BufferedWriter writer = new BufferedWriter(file.openWriter()); 
  ... write resource file ... 
} 
 
private void generateServiceImplFile(List<String> declarations) throws Exception { 
  JavaFileObject file = processingEnv.getFiler().createSourceFile("x.y.z.FooServiceImpl"); 
  BufferedWriter writer = new BufferedWriter(file.openWriter()); 
  ... write source code ... 
} 

我目前在 pom.xml文件中声明依赖项,如下所示:
<!-- Dependency for the @Foo annotation --> 
<dependency> 
  <groupId>x.y.z</groupId> 
  <artifactId>foo-annotations</artifactId> 
  <scope>compile</scope> 
</dependency> 
<!-- Dependency for the @Foo annotation processor --> 
<dependency> 
  <groupId>x.y.z</groupId> 
  <artifactId>foo-annotations-processor</artifactId> 
  <scope>compile</scope> 
</dependency> 

我使用的是JDK 1.7,即 maven-compiler-plugin 3.1版。注释处理器通过其存在于类路径上而被调用。我没有添加任何处理器插件等,也没有调整编译器插件等以使其正常工作。

编辑#2 :我对 maven-compiler-plugin进行了以下更改:
<plugin> 
  <groupId>org.apache.maven.plugins</groupId> 
  <artifactId>maven-compiler-plugin</artifactId> 
  <version>3.1</version> 
  <executions> 
    <!-- Disable annotation processing for default compile execution --> 
    <execution> 
      <id>default-compile</id> 
      <goals> 
        <goal>compile</goal> 
      </goals> 
      <configuration> 
        <proc>none</proc> 
      </configuration> 
    </execution> 
    <!-- Only annotation process in this execution, with generated code  
         going to generated-test-sources directory. --> 
    <execution> 
      <id>compile-with-annotations-processor</id> 
      <goals> 
        <goal>compile</goal> 
      </goals> 
      <configuration> 
        <proc>only</proc> 
        <generatedSourcesDirectory> 
          ${project.build.directory}/generated-test-sources/test-annotations 
        </generatedSourcesDirectory> 
      </configuration> 
    </execution> 
  </executions> 
</plugin> 

这将禁用 default-compile执行的注释处理,并且 compile-with-annotations-processing执行仅执行注释处理,将生成的源放入target \ generate-test-sources \ test-annotations目录中。

运行此命令时,尽管资源文件仍出现在target / classes目录中,但在target / generate-test-sources / test-annotations目录中看到了生成的java文件。我猜我可以通过将 generateResourceFile()方法更改为使用 StandardLocation.SOURCE_OUTPUT而不是 StandardLocation.CLASS_OUTPUT来解决此问题。

此外,此修复程序不能优雅地处理多个注释处理器。我真的只希望在 default-compile执行过程中禁用此特定注释处理器,而只在 compile-with-annotations-processing执行过程中启用该处理器(具有不同的源目录)。否则,如果我添加另一个(不相关的)注释处理器,则其生成的代码将不会出现在预期的位置。

编辑#3 :也许一个更简单的解决方案是允许编译器正常运行批注处理器,然后使用 maven-antrun-plugin将生成的文件从target \ generated-sources移到target \ generate-test-sources中,例。

编辑#4 :我认为我已经使用上面提到的 maven-antrun-plugin解决了这个问题:
  • 配置maven-antrun-plugin将文件从目标/生成源/注释移动到目标/生成测试源/测试注释,并从目标/类/ META-INF /服务移动到目标/测试类/ META-INF /服务,在期间编译阶段。
  • 配置build-helper-maven-plugin以将目标/生成测试源添加到生成测试源阶段。

  • 我的foo.jar和foo-test.jar似乎正确构建了:-)

    编辑#5 :我发现了一个名为 maven-processor-plugin的插件,并且已将其配置为在生产代码的 generate-test-sources 阶段运行,并将输出目录设置为target / generate-test-sources / annotations和目标/测试类别。奇迹般有效。因此,现在完全不需要 maven_antrun_plugin

    请您参考如下方法:

    我发现了一个名为maven-processor-plugin的插件,并将其配置为在生产代码上的generate-test-sources阶段运行,并将输出目录设置为target / generate-test-sources / annotations和target / test-classs。奇迹般有效。因此,现在完全不需要maven_antrun_plugin

    我想出的另一种解决方案(因为有时使用maven-compiler-plugin而不是maven-processor-plugin更好)是在compile阶段使用注释处理器生成代码,以便代码最终位于通常的target / generation-sources / annotations目录中。同一模块中的测试代码可以访问此位置,并且测试运行良好。然后,我将maven-jar-plugin配置为从artifactId .jar中排除生成的代码,并将生成的代码包含在名为artifactId -test-libs.jar的新工件中。然后,其他模块在artifactId -test-libs上添加测试依赖项。


    评论关闭
    IT序号网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!