使用AnnotationProcessor构建Maven,解析src / main / java中的文件,并生成源代码到generate-test-sources / test-annotations

我正在使用maven 3.0.3和Java7。

我有一个AnnotationProcessor,它应该解析src/main/java不是 src/test/java )中带注释的java文件,并为JUnit-Tests生成Helper-Classes。 这些Helper-Class应该存储在target/generated-test-sources/test-annotations因为它们使用的库只在测试范围内可用。 (注意:只要这个依赖关系不在测试范围内,一切都可以正常工作,但是编译就会失败。它肯定只在测试范围/unit testing和编译测试类时才需要。)

我试了好几个配置而没有任何运气:

  1. 我将maven-compiler-plugin配置为在compile:compile期间使用AnnotationProcessor。 生成的HelperClass将存储在generated-sources/annotations不在 generated-test-sources/test-annotations中。 结果是,不会使用Test-Scoped依赖项。 由于编译错误“无法找到符号”,构建失败。 失败

  2. 我使用了上面的配置并重新定义了generatedSourcesDirectory:

      ${project.build.directory}/generated-test-sources/test-annotations  

    生成的类将按预期存储在generated-test-sources/test-annotations中,但构建仍然失败,因为它尝试按上述方式编译该文件并错过了测试范围的依赖项。 失败

  3. 我尝试使用上面的配置并排除**/generated-test-sources/test-annotations/**/*.java以防止编译器在此阶段进行编译:

      **/generated-test-sources/test-annotations/**/*.java  

    没运气。 与上面相同的编译器错误。 失败

  4. 我将maven-compiler-plugin配置为在test-compile:testCompile期间使用AnnotationProcessor test-compile:testCompile 。 HelperClass理论上可能是在generated-test-sources/test-annotationsgenerated-test-sources/test-annotations ,但是AnnotationProcessor不会偶然发现位于src/main/java的带注释的类,而不是src/test/java中的AFAIK test-compile:testCompile期间test-compile:testCompile范围test-compile:testCompile 。 因此,找不到Annotated类,HelperClass将不会生成,因此不能存储在generated-test-sources失败

  5. 试图在compile:testCompile期间运行compile:testCompiletest-compile:compile ,这在两种情况下都导致src / main / java的类尚未编译 – 因此编译错误。 失败

我真正想做的是:

  1. 配置编译器在compile:compile期间使用AnnotationProcessor compile:compile生成我的HelperClass到${project.build.directory}/generated-test-sources/test-annotations 但不要让maven编译它
  2. 然后在test-compile:testCompile期间test-compile:testCompile

我没有这样做。 我不确定我是否缺少重要的maven基础知识(概念),或者排除配置是否存在问题,或者不管它是什么。

非常感谢任何帮助。 提前致谢。

我用includestestExcludestestExcludes等进行了几次测试(我发现这些测试的记录非常糟糕)。 似乎maven只是忽略了这些配置设置。 真的不能相信它,但是虽然它表明包含和排除已经正确配置并且使用了这些配置(mvn -X clean install),但它仍然编译了排除的文件或者没有编译包含的文件。 (顺便说一句:我也从CLI测试过它,因为我发现有些IDE仍然忽略这些设置。)在那里发现任何解决方案,比如添加资源目录,包括,排除,在test-compile:testCompile期间定义generatedTestSourcesDirectory test-compile:testCompile以匹配generatedSourcesDirectory of compile:compile根本没用。 随你。

我找到了解决问题的方法如下:

  1. 让第一个编译步骤( compile:compile )只使用Annotation-Processors,但不编译生成的类: only 。 将generatedSourcesDirectory定义为应生成测试源的位置: ${project.build.directory}/generated-test-sources/test-annotations
  2. 使用build-helper-maven-plugin在正确的阶段和目标中添加test-source-directory。 然后执行隐式test-compile:testCompile ,并将生成的类sourcepath添加到普通源路径中。

以下是我的配置。 请注意,我需要在实际问题发生之前生成其他内容,并且必须生成generated-sources/annotations ,因此解决方案需要的编译步骤超过一个。

所以,就是这样:

    org.apache.maven.plugins maven-compiler-plugin 3.0  1.7 1.7 ${project.build.sourceEncoding}     default-compile  compile     compile-TestHelperClass  compile    org.my.UnitTestGenerationProcessor  ${project.build.directory}/generated-test-sources/test-annotations  only        org.codehaus.mojo build-helper-maven-plugin 1.8   add-test-source generate-test-sources  add-test-source    ${project.build.directory}/generated-test-sources/test-annotations        

说实话,maven-compiler-plugin一般很糟糕。 我使用的第三方插件似乎总能正常运行。 我只是将none用于maven-compiler-plugin,然后:

   org.bsc.maven maven-processor-plugin   annogen generate-sources  process  false    xapi.dev.processor.AnnotationMirrorProcessor   ${project.build.directory}/generated-sources/annotations true   ${project.basedir}/../api/src/main/java       

您可以查看此博客文章: http : //deors.wordpress.com/2011/10/08/annotation-processors/

看起来您需要在pom.xml中设置以下内容

建立>插件>插件>配置> compilerArgument> -proc:无

我不确定这是否适用于您的特定情况,但我昨天正在处理注释,并认为这可能会对您有所帮助。

看起来这个参数可以让你在没有任何注释处理器的情况下进行编译。 然后,您可以在生命周期的稍后阶段使用它们进行编译。

我有一个类似的问题,并尝试了建议的解决方案(两次执行maven-compiler-plugin,第一次使用proc:none ,第二次使用proc:only )但遇到了以下问题:

1)运行mvn clean install :在运行注释处理器之前,两个执行( proc:noneproc:only )都将编译源代码并生成类文件:

 [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ foo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 6 source files to \foo\target\classes [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (process-annotations) @ foo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 6 source files to \foo\target\classes [MyAnnotationProcessor] processing ... 

2)在上一次mvn install之后运行mvn install :两个执行( proc:noneproc:only )确定类文件是最新的并且什么都不做,并且注释处理器没有运行:

 [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ foo --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (process-annotations) @ foo --- [INFO] Nothing to compile - all classes are up to date 

所以在第一种情况下,java文件被编译两次(我的一个模块有数千个文件,这会显着影响构建时间)。 在第二种情况下,没有任何事情发生,因为类文件已经存在。 这是使用maven-compiler-plugin 3.1和3.0版本。

对于maven-compiler-plugin版本2.5.1,第二次执行( proc:only )将始终确定类文件是最新的并且不运行注释处理器,无论我是运行mvn clean install还是mvn install ,所以第二次执行执行毫无意义。

该插件配置如下:

  org.apache.maven.plugins maven-compiler-plugin 3.1  1.7 1.7    default-compile  none    process-annotations compile  only  MyAnnotationProcessor     

因此proc:only选项似乎在版本3.0和3.1中编译源代码(使其与proc:both相同proc:both ,这会影响性能)或在版本2.5.1中不采取任何操作(使其与proc:none相同,这会影响function)。

不知道如何解决这个问题……

编辑#1

详细输出包括以下内容:

 [INFO] --- maven-compiler-plugin:3.1:compile (process-annotations) @ foo --- [DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-compiler-plugin:3.1:compile' with basic configurator --> [DEBUG] (f) annotationProcessors = [MyAnnotationProcessor] [DEBUG] (f) basedir = \foo [DEBUG] (f) buildDirectory = \foo\target [DEBUG] (f) classpathElements = [\foo\target\classes, ...] [DEBUG] (f) compileSourceRoots = [\foo\src\main\java] [DEBUG] (f) compilerId = javac [DEBUG] (f) debug = true [DEBUG] (f) failOnError = true [DEBUG] (f) forceJavacCompilerUse = false [DEBUG] (f) fork = false [DEBUG] (f) generatedSourcesDirectory = \foo\target\generated-sources\annotations [DEBUG] (f) mojoExecution = org.apache.maven.plugins:maven-compiler-plugin:3.1:compile {execution: process-annotations} [DEBUG] (f) optimize = false [DEBUG] (f) outputDirectory = \foo\target\classes [DEBUG] (f) proc = only [DEBUG] (f) projectArtifact = foo:jar:1.0-SNAPSHOT [DEBUG] (f) showDeprecation = false [DEBUG] (f) showWarnings = false [DEBUG] (f) skipMultiThreadWarning = false [DEBUG] (f) source = 1.7 [DEBUG] (f) staleMillis = 0 [DEBUG] (f) target = 1.7 [DEBUG] (f) useIncrementalCompilation = true [DEBUG] (f) verbose = true [DEBUG] (f) mavenSession = org.apache.maven.execution.MavenSession@6fb65730 [DEBUG] (f) session = org.apache.maven.execution.MavenSession@6fb65730 [DEBUG] -- end configuration -- [DEBUG] Using compiler 'javac'. [DEBUG] Source directories: [\foo\src\main\java] [DEBUG] Classpath: [\foo\target\classes ... ] [DEBUG] Output directory: \foo\target\classes [DEBUG] CompilerReuseStrategy: reuseCreated [DEBUG] useIncrementalCompilation enabled [INFO] Changes detected - recompiling the module! [DEBUG] Classpath: [DEBUG] \foo\target\classes ... [DEBUG] Source roots: [DEBUG] \foo\src\main\java [DEBUG] Command line options: [DEBUG] -d \foo\target\classes -classpath \foo\target\classes;...; -sourcepath \foo\src\main\java; -s \foo\target\generated-sources\annotations -proc:only -processor MyAnnotationProcessor -g -verbose -nowarn -target 1.7 -source 1.7 [DEBUG] incrementalBuildHelper#beforeRebuildExecution [INFO] Compiling 6 source files to \foo\target\classes [parsing started RegularFileObject[\foo\src\main\java\Foo.java]] [parsing completed 0ms] ... [search path for source files: \foo\src\main\java] [MyAnnotationProcessor] processing ... 

即使有一个proc:only在编译器选项中仍然有[parsing started RegularFileObject]条目…也许它只是记录但实际上加载了类文件?