Maven注解处理器未找到。

15

我刚接触注解处理,现在想用Maven自动化处理。我已经将以下内容放入我的pom.xml文件中:

<plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <annotationProcessors>
                    <annotationProcessor>
                        co.aurasphere.revolver.annotation.processor.InjectAnnotationProcessor</annotationProcessor>
                    <annotationProcessor>
                        co.aurasphere.revolver.annotation.processor.RevolverContextAnnotationProcessor</annotationProcessor>
                </annotationProcessors>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>

问题在于当我尝试构建项目时,由于Maven找不到处理器,所以我遇到了CompilationFailureException。

我找到了类似的其他问题,通过将依赖项放在插件外部来解决。我尝试了那个方法,但对我来说没有任何改变。

我有什么遗漏吗?

谢谢。

编辑

这是我的另一个项目上的依赖项,其中包含处理器和注释:

    <dependencies>
    <dependency>
        <groupId>co.aurasphere</groupId>
        <artifactId>revolver-annotation-processor</artifactId>
        <version>0.0.3-SNAPSHOT</version>
    </dependency>
</dependencies>

编辑2:

经过进一步调查,我决定反编译使用Maven构建的处理器JAR文件,结果发现……我的类不在里面。由于某些原因,Maven没有将我的类编译到JAR文件中,这就是为什么找不到这些类的原因。我尝试找出构建过程中的错误(这在以前从未发生过,而且我已经使用Maven有一段时间了……)。

首先,该项目的打包格式为jar。 所有类都位于src/main/java下。 我已经检查了我的pom.xml文件,确保类路径和源路径相同。

这是处理器的pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>co.aurasphere</groupId>
<artifactId>revolver-annotation-processor</artifactId>
<version>0.0.3-SNAPSHOT</version>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins> 
</build>
<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.7</version>
    </dependency>


</dependencies>

编辑3

这里是处理器项目执行“maven clean install”命令的输出结果。不幸的是,输出结果太长了,我只能发布外部链接,尽管我知道这样做并不好。

编辑4

这里是我的依赖层次结构截图:EclipseFile System

由于该项目最初是作为 Eclipse 简单 Java 项目创建的,然后转换为 Maven 项目,因此我尝试创建一个新的 Maven 项目,并将所有内容移动到新项目中,希望问题出在 Eclipse 插件上误操作了,但错误仍然存在。


3
请发布一下您如何定义依赖项到co.aurasphere.revolver...包。它们不是在您尝试编译的项目内部,对吗? - ppeterka
3
请注意,在构建使用注解处理器的项目之前,您必须先构建注解处理器本身。 - chrylis -cautiouslyoptimistic-
4个回答

23
这是上面@Aurasphere所提供的答案的扩展版本。希望这能够解释所提出的解决方案如何工作。
首先,了解一下这里正在发生什么背景。假设我们需要一个自定义注解处理器。我们实现它并将其放入JAR中作为Maven工件,以便其他项目可以使用它。在编译此类项目时,我们希望Java编译器能够识别我们的注解处理器并适当地使用它。为了实现这一点,需要告诉编译器有一个新的自定义处理器。编译器查找资源并检查“META-INF / services / javax.annotation.processing.Processor”文件中列出的类的FQN。它会尝试在类路径中查找这些类并加载它们以运行在当前编译的类上使用的注解的处理。
因此,我们希望在此文件中提到我们的自定义类。我们可以要求库的用户手动放置此文件,但这不直观,用户可能会感到沮丧,为什么所承诺的注解处理不起作用。这就是为什么我们可能希望提前准备此文件,并将其与处理器一起交付到我们Maven工件的JAR中的原因。
问题是,如果我们只是将具有自定义处理器FQN的文件放置在其中,它将在“构建我们的工件”的编译器期间触发,并且由于处理器本身尚未编译,因此编译器将显示有关其错误的消息。因此,我们需要跳过注解处理以避免这种情况。可以使用“-proc:none”或使用Maven来完成:
<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <proc>none</proc>
    </configuration>
</plugin>

我们可能需要使用注解处理器来进行单元测试。在Maven中,测试编译是在主要源代码构建完成之后进行的,并且所有类已经可用,包括我们的处理器。我们只需要在测试源代码处理过程中添加一个特殊步骤,就可以使用我们的注解处理器。可以使用以下方式实现:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
        <execution>
            <id>process-test-annotations</id>
            <phase>generate-test-resources</phase>
            <goals>
                <goal>testCompile</goal>
            </goals>
            <configuration>
                <proc>only</proc>
                <annotationProcessors>
                    <annotationProcessor>fully.qualified.Name</annotationProcessor>
                </annotationProcessors>
            </configuration>
        </execution>
    </executions>
</plugin>

2
这个答案真的帮了我很多,而且立刻就起作用了。非常感谢! - monamona

8

我已经自己找到了答案。我发现问题出在META-INF/services/目录下的javax.annotation.processing.Processor文件中,这个文件配置了注解处理器的类。为了解决这个问题,我需要在我的处理器项目的pom.xml配置文件中添加以下内容:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <compilerArgument>
                    -proc:none
                </compilerArgument>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

这使得Maven将类构建到实际的jar文件中,并解决了问题。我不知道这是否是一个错误,但对我来说看起来很奇怪。感谢大家的帮助!


1
最简单的方法是在revolver-annotation-processor构件的META-INF/services目录中注册注解处理器,无需Maven编译器配置。
检查是否已经注册,如果没有,且您控制源代码,则可以自己注册。

https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html

如果您控制源代码,我建议将处理器打包在与注释相同的构件中。这样,每当您使用其中一种注释时,编译器也会选择注释处理器。

0

这里接受的答案通过禁用所有注解处理来实现,但如果在编译期间需要运行其他注解处理器,则可能不适用。相反,在后处理步骤中可以添加列出新编译的注解处理器的SPI配置文件。我向我的项目添加了一个目录src/main/post-resources和这个插件配置:

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.3.0</version>
  <executions>
    <execution>
      <id>annotation-processor-spi</id>
      <phase>process-classes</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/post-resources</directory>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接