我正在使用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
中,因为它们使用的库只在测试范围内可用。 (注意:只要这个依赖关系不在测试范围内,一切都可以正常工作,但是编译一旦失败就会失败。它肯定只在测试范围内/单元测试和编译测试类时才需要。)
我试了好几个配置而没有任何运气:
我在maven-compiler-plugin
期间将compile:compile
配置为使用AnnotationProcessor。生成的HelperClass将存储在generated-sources/annotations
中。根据需要在generated-test-sources/test-annotations
中不。结果是,不会使用Test-Scoped依赖项。由于编译错误“无法找到符号”,构建失败。 故障
我使用了上面的配置并重新定义了generatedSourcesDirectory:
<generatedSourcesDirectory>
${project.build.directory}/generated-test-sources/test-annotations
</generatedSourcesDirectory>
生成的类将按预期存储在generated-test-sources/test-annotations
中,但构建仍然失败,因为它尝试按上述方式编译该文件并错过了测试范围的依赖项。 故障
我尝试使用上面的配置并排除了**/generated-test-sources/test-annotations/**/*.java
,以防止编译器在此阶段进行编译:
<excludes>
<exclude>**/generated-test-sources/test-annotations/**/*.java</exclude>
</excludes>
没有运气。与上面相同的编译器错误。 故障 我在maven-compiler-plugin
期间将test-compile:testCompile
配置为使用AnnotationProcessor。理论上,HelperClass可能是在generated-test-sources/test-annotations
中生成的,但是AnnotationProcessor不会偶然发现位于src/main/java
的注释类,而不会发现src/test/java
中的注释类,这是编译范围的AFAIK在test-compile:testCompile
期间。因此,找不到Annotated类,HelperClass将不会生成,因此不能存储在generated-test-sources
中。 故障
试图在compile:testCompile
和test-compile:compile
期间运行它,这在两种情况下都导致尚未编译的src / main / java类 - 因此编译错误。 故障
我真正想做的是:
compile:compile
期间使用AnnotationProcessor生成我的HelperClass到${project.build.directory}/generated-test-sources/test-annotations
但不要让maven编译它 test-compile:testCompile
。我没有这样做。我不确定我是否缺少重要的maven基础知识(概念),或者排除配置是否有问题,或者它是什么。
非常感谢任何帮助。提前谢谢。
答案 0 :(得分:4)
我使用includes
,excludes
,testExcludes
等进行了多次测试(我发现这些测试的记录非常糟糕)。似乎maven只是忽略了这些配置设置。真的不能相信它,但是虽然它表明包含和排除已经正确配置并且使用了这些配置(mvn -X clean install),但它仍然编译了排除的文件或者没有编译包含的文件。 (顺便说一下:我也是从CLI测试过的,因为我发现有些IDE仍然忽略这些设置。)
在那里发现的任何解决方案,例如添加资源目录,包括,排除,在generatedTestSourcesDirectory
期间定义test-compile:testCompile
以匹配generatedSourcesDirectory
的{{1}}根本不起作用。
不管。
我找到了解决问题的方法,如下所示:
compile:compile
)仅使用Annotation-Processors,但不编译生成的类:compile:compile
。将<proc>only</proc>
定义为应生成测试源的位置:generatedSourcesDirectory
。${project.build.directory}/generated-test-sources/test-annotations
在正确的阶段和目标中添加test-source-directory。
然后执行隐式build-helper-maven-plugin
,并将生成的类sourcepath添加到普通源路径中。 以下是我的配置。请注意,我需要在实际问题出现之前生成其他内容,并且必须生成test-compile:testCompile
,因此解决方案需要的编译步骤超过一个。
所以,就是这样:
generated-sources/annotations
答案 1 :(得分:1)
说实话,maven-compiler-plugin一般很糟糕。我使用第三方插件,似乎总能正常工作。我只使用<proc>none</proc>
作为maven-compiler-plugin,然后:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>annogen</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<inherited>false</inherited>
<configuration>
<processors>
<processor>
xapi.dev.processor.AnnotationMirrorProcessor
</processor>
</processors>
<outputDirectory>${project.build.directory}/generated-sources/annotations</outputDirectory>
<appendSourceArtifacts>true</appendSourceArtifacts>
<additionalSourceDirectories>
<additionalSourceDirectory>
${project.basedir}/../api/src/main/java
</additionalSourceDirectory>
</additionalSourceDirectories>
</configuration>
</execution>
</executions>
</plugin>
答案 2 :(得分:0)
您可以查看此博文: http://deors.wordpress.com/2011/10/08/annotation-processors/
您似乎需要在pom.xml中设置以下内容
构建&GT;插件&GT;插件&GT;结构&gt;&compilerArgument GT; -proc:无
我不确定这是否适用于您的特定情况,但我昨天正在处理注释,并认为这可能会对您有所帮助。
看起来这个参数可以让你在没有任何注释处理器的情况下进行编译。然后你可以在生命周期的后期编译它们。
答案 3 :(得分:0)
我有类似的问题,并尝试了建议的解决方案(两次执行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 <mumble>\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 <mumble>\foo\target\classes
[MyAnnotationProcessor] processing ...
2)在上一次安装之后运行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
,所以第二次执行毫无意义。
插件配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<proc>none</proc>
</configuration>
</execution>
<execution>
<id>process-annotations</id>
<goals><goal>compile</goal></goals>
<configuration>
<proc>only</proc>
<annotationProcessors>
<annotationProcessor>MyAnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</execution>
</plugin>
所以proc:only
选项似乎在版本3.0和3.1中编译源代码(使其与proc:both
相同,这会影响性能)或在版本2.5.1中不采取任何操作(使其成为与影响功能的proc:none
相同。
不确定如何解决这个问题...
编辑#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 = <mumble>\foo
[DEBUG] (f) buildDirectory = <mumble>\foo\target
[DEBUG] (f) classpathElements = [<mumble>\foo\target\classes, ...]
[DEBUG] (f) compileSourceRoots = [<mumble>\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 = <mumble>\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 = <mumble>\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: [<mumble>\foo\src\main\java]
[DEBUG] Classpath: [<mumble>\foo\target\classes ... ]
[DEBUG] Output directory: <mumble>\foo\target\classes
[DEBUG] CompilerReuseStrategy: reuseCreated
[DEBUG] useIncrementalCompilation enabled
[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] <mumble>\foo\target\classes ...
[DEBUG] Source roots:
[DEBUG] <mumble>\foo\src\main\java
[DEBUG] Command line options:
[DEBUG] -d <mumble>\foo\target\classes
-classpath <mumble>\foo\target\classes;...;
-sourcepath <mumble>\foo\src\main\java;
-s <mumble>\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 <mumble>\foo\target\classes
[parsing started RegularFileObject[<mumble>\foo\src\main\java\Foo.java]]
[parsing completed 0ms]
...
[search path for source files: <mumble>\foo\src\main\java]
[MyAnnotationProcessor] processing ...
即使编译器选项中有proc:only
,仍然有一个[parsing started RegularFileObject]
条目......也许它只是记录但实际加载了类文件?