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

16

我正努力学习如何制作自定义注解处理器,但是我卡在尝试调试它上了。

我已经成功以调试模式运行了 javac 编译器(使用 mvnDebug clean install)(使用别人的带有注解处理器的项目),并使用 IntelliJ IDEA 连接到它,使它在注解处理器的断点处停止。


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

public class MyProcessor extends AbstractProcessor {...}

我们是否可以将其作为注释处理器连接到maven的构建过程中?这样它就会先被编译,然后整个项目都将使用注释处理器进行编译。

此外,据我所知,注释处理器需要某种类型的META INF文件,可以通过类似google autoservices注释处理器生成。

因此,也许可以使用基于maven的构建过程,首先运行autoservices,然后编译扩展AbstractProcessor类的类作为注释处理器,最后使用我们自己的注释处理器(以及javac编译器的调试模式)对整个项目进行编译。


1
我的首选策略是在单元测试中进行调试。 - David Pérez Cabrera
1
@DavidPérezCabrera 是的,但出于学习的目的,我想检查当前存在的变量。 - PaperTsar
1个回答

27

这是食谱。

附注:在某些情况下,我讲得非常详细,请跳过您已经了解如何执行的部分。

  1. 首先,下载并安装 Maven,然后下载并安装 IntelliJ IDEA(以下简称 IDEA)。 (如果您不知道如何使用Windows CMD,请参阅此短教程 ,还有: 如何打开命令提示符

  2. 在IDEA中创建一个没有任何原型的Maven项目。 然后在src> main> java中创建一些软件包。

  3. 创建一个扩展 javax.annotation.processing.AbstractProcessor 的类。

  4. 插入一些最小的代码,以使其工作。(不要忘记类声明顶部的注释!)

    假设注释完整路径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();
        }
    }
    
  5. 在相同的包中创建一个注释。

  6. public @interface Factory {
    
    }
    
    在该项目中,可能有一个目录src > test > java,在其中创建一个与您之前创建的包同名的新包。然后在其中创建一个以“Test”结尾的类(例如:MyProcessorTest)。然后使用您之前创建的新注释类型(@Factory)对此类进行注释。
    @Factory
    public class MyProcessorTest {
    
    }
    
  7. 现在,为了使注解处理器起作用,它们必须在META-INF中有一些文件。为了实现这一点,我们将使用另一个名为autoservice的注解处理器。因此,在pom.xml文件中插入它的依赖项。

  8. <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>
    
  9. 在我们的处理器类中使用@AutoService(Processor.class)进行注释。

  10. 现在,我们需要在IDEA中设置远程调试配置。要做到这一点,请转到Run > Edit Configurations,点击左上角的绿色+按钮,选择remote。将其命名为“mvnDebug”,将主机设置为localhost,将端口设置为8000,按下ok就可以了。

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

  12. 打开Windows命令提示符,导航到您的项目目录,在其中pom.xml所在的位置。然后键入mvnDebug clean install。如果一切都设置正确,它应该显示类似于“Listening for transport dt_socket at address: 8000”的内容。

  13. 回到IDEA并执行我们刚刚创建的mvnDebug配置。如果一切都设置正确,它应该显示类似于“Connected to the target VM, address: 'localhost: 8000', transport: 'socket'” 的内容。

  14. 返回命令提示符,如果没有发生任何事情,请按某个键唤醒它。

  15. 如果所有设置都正确,IDEA将停在断点处,暂停javac(Java编译器)的执行。


  16. 有关注释处理的其他教程


那就是逐步教程所缺失的,谢谢,一切正常运作。 - vcmkrtchyan

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