使用 Intellij 和 Maven 调试 Java 个注释处理器

Debug Java annotation processors using Intellij and Maven

我正在尝试学习如何制作自定义注释处理器,但我一直在尝试调试它。

我已经设法 运行 调试模式下的 javac 编译器(使用 mvnDebug clean install)(使用带有注释处理器的其他项目),连接到它与 IntelliJ IDEA 并让它在注释处理器的断点处停止。


如果我们项目的某个包中有类似的东西,就像任何其他包一样class(例如,没有特殊配置或任何东西):

public class MyProcessor extends AbstractProcessor {...}

我们能否以某种方式将其作为注解处理器挂接到 maven 的构建过程中?所以它首先被编译,然后整个项目在注解处理器处于活动状态的情况下被编译。

此外,据我所知,注释处理器需要某种 META INF 文件,可以使用 google autoservices 注释处理器之类的东西生成。

所以也许是一个 Maven 构建过程,我们首先有 autoservices 运行,然后 class 扩展编译为注释处理器的 AbstractProcessor,最后用我们的代码编译整个项目自己的注释处理器处于活动状态(并且 javac 编译器处于调试模式)。

这是食谱。

旁注:我在某些情况下做得非常详细,请跳过您已经知道该怎么做的部分。

  1. 首先,download and install Maven, then download and install IntelliJ IDEA (referred to as IDEA from here on). (If you don't know how to use Windows CMD, here is a short tutorial for it, also: how to open the command prompt)

  2. 在 IDEA 中创建一个没有任何 Archetype 的 Maven 项目。然后在 src > main > java

  3. 中创建一些包
  4. 创建一个扩展 javax.annotation.processing.AbstractProcessor.

  5. 的 Class
  6. 插入一些最少的代码,使其正常工作。 (不要忘记 class 声明顶部的注释!)

    假设注解完整路径core.Factory,代码看起来像

    @SupportedAnnotationTypes("core.Factory")
    public class MyProcessor extends AbstractProcessor {
    Messager messager;
    
        @Override
        public void init(ProcessingEnvironment env) {
            messager = env.getMessager();
            super.init(env);
        }
    
        @Override
        public boolean process(Set<? extends TypeElement> annotations,       RoundEnvironment roundEnv) {
            for (TypeElement te : annotations)
                for (Element e : roundEnv.getElementsAnnotatedWith(te))
                    messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " +   e.toString());
            return true;
        }
    
        @Override
        public SourceVersion getSupportedSourceVersion() {
            return SourceVersion.latestSupported();
        }
    }
    
  7. 在同一个包中创建注释。

    public @interface Factory {
    
    }
    
  8. 在项目中可能有一个目录src > test > java,在那里创建另一个与你的包同名的包较早创建。然后在其中创建一个名称以"Test"结尾的Class(例如:MyProcessorTest)。然后使用您之前创建的新注释类型 (@Factory) 注释此 class。

    @Factory
    public class MyProcessorTest {
    
    }
    
  9. 现在,注释处理器要工作,它们必须在 META-INF 中有一些文件。为此,我们将使用另一个名为 autoservice 的注解处理器。所以在 pom.xml 文件中插入它的依赖项。

    <dependencies>
        <dependency>
            <groupId>com.google.auto.service</groupId>
            <artifactId>auto-service</artifactId>
            <version>1.0-rc2</version>
        </dependency>
    </dependencies>
    

    7.1 旁注: 由于某些原因,如果我没有明确指定,Maven 项目使用 Java 1.5。要强制它与 Java 1.8 一起使用,请将其插入 pom.xml 文件。

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  10. @AutoService(Processor.class)注释我们的处理器Class。

  11. 现在,我们必须在IDEA中设置远程调试器配置。为此,请转到 运行 > 编辑配置,单击左上角的绿色 + 按钮,select 遥控器。将其命名为 "mvnDebug",将主机设置为 localhost,将端口设置为 8000,按确定就可以了。

  12. 在处理器的 process 方法中设置一个断点。

  13. 打开 Windows 命令提示符,导航到 pom.xml 所在的项目目录。然后输入 mvnDebug clean install。如果一切设置正确,它应该会显示类似 "Listening for transport dt_socket at address: 8000".

  14. 的内容
  15. 回到IDEA,执行我们刚才做的mvnDebug配置。如果一切设置正确,它应该显示类似 "Connected to the target VM, address: 'localhost:8000', transport: 'socket'".

  16. 的内容
  17. 返回命令提示符,如果没有任何反应,请按某个键将其唤醒。

  18. 如果一切设置正确,IDEA 将在断点处停止,暂停 javac(Java 编译器)的执行。


关于注释处理的其他教程