使用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和编译测试类时才需要。)
我试了好几个配置而没有任何运气:
-
我将
maven-compiler-plugin
配置为在compile:compile
期间使用AnnotationProcessor。 生成的HelperClass将存储在generated-sources/annotations
。 不在generated-test-sources/test-annotations
中。 结果是,不会使用Test-Scoped依赖项。 由于编译错误“无法找到符号”,构建失败。 失败 -
我使用了上面的配置并重新定义了generatedSourcesDirectory:
${project.build.directory}/generated-test-sources/test-annotations
生成的类将按预期存储在
generated-test-sources/test-annotations
中,但构建仍然失败,因为它尝试按上述方式编译该文件并错过了测试范围的依赖项。 失败 -
我尝试使用上面的配置并排除
**/generated-test-sources/test-annotations/**/*.java
以防止编译器在此阶段进行编译:**/generated-test-sources/test-annotations/**/*.java
没运气。 与上面相同的编译器错误。 失败
-
我将
maven-compiler-plugin
配置为在test-compile:testCompile
期间使用AnnotationProcessortest-compile:testCompile
。 HelperClass理论上可能是在generated-test-sources/test-annotations
中generated-test-sources/test-annotations
,但是AnnotationProcessor不会偶然发现位于src/main/java
的带注释的类,而不是src/test/java
中的AFAIKtest-compile:testCompile
期间test-compile:testCompile
范围test-compile:testCompile
。 因此,找不到Annotated类,HelperClass将不会生成,因此不能存储在generated-test-sources
。 失败 -
试图在
compile:testCompile
期间运行compile:testCompile
和test-compile:compile
,这在两种情况下都导致src / main / java的类尚未编译 – 因此编译错误。 失败
我真正想做的是:
- 配置编译器在
compile:compile
期间使用AnnotationProcessorcompile:compile
生成我的HelperClass到${project.build.directory}/generated-test-sources/test-annotations
但不要让maven编译它 - 然后在
test-compile:testCompile
期间test-compile:testCompile
。
我没有这样做。 我不确定我是否缺少重要的maven基础知识(概念),或者排除配置是否存在问题,或者不管它是什么。
非常感谢任何帮助。 提前致谢。
我用includes
, testExcludes
, testExcludes
等进行了几次测试(我发现这些测试的记录非常糟糕)。 似乎maven只是忽略了这些配置设置。 真的不能相信它,但是虽然它表明包含和排除已经正确配置并且使用了这些配置(mvn -X clean install),但它仍然编译了排除的文件或者没有编译包含的文件。 (顺便说一句:我也从CLI测试过它,因为我发现有些IDE仍然忽略这些设置。)在那里发现任何解决方案,比如添加资源目录,包括,排除,在test-compile:testCompile
期间定义generatedTestSourcesDirectory
test-compile:testCompile
以匹配generatedSourcesDirectory
of compile:compile
根本没用。 随你。
我找到了解决问题的方法如下:
- 让第一个编译步骤(
compile:compile
)只使用Annotation-Processors,但不编译生成的类:
。 将only generatedSourcesDirectory
定义为应生成测试源的位置:${project.build.directory}/generated-test-sources/test-annotations
。 - 使用
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一般很糟糕。 我使用的第三方插件似乎总能正常运行。 我只是将
用于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:none
和proc: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:none
和proc: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]
条目…也许它只是记录但实际上加载了类文件?