使用 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 编译器处于调试模式)。
这是食谱。
旁注:我在某些情况下做得非常详细,请跳过您已经知道该怎么做的部分。
首先,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)
在 IDEA 中创建一个没有任何 Archetype 的 Maven 项目。然后在 src > main > java
中创建一些包
创建一个扩展 javax.annotation.processing.AbstractProcessor.
的 Class
插入一些最少的代码,使其正常工作。 (不要忘记 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();
}
}
在同一个包中创建注释。
public @interface Factory {
}
在项目中可能有一个目录src > test > java,在那里创建另一个与你的包同名的包较早创建。然后在其中创建一个名称以"Test"结尾的Class(例如:MyProcessorTest)。然后使用您之前创建的新注释类型 (@Factory) 注释此 class。
@Factory
public class MyProcessorTest {
}
现在,注释处理器要工作,它们必须在 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>
用@AutoService(Processor.class)
注释我们的处理器Class。
现在,我们必须在IDEA中设置远程调试器配置。为此,请转到 运行 > 编辑配置,单击左上角的绿色 + 按钮,select 遥控器。将其命名为 "mvnDebug",将主机设置为 localhost,将端口设置为 8000,按确定就可以了。
在处理器的 process 方法中设置一个断点。
打开 Windows 命令提示符,导航到 pom.xml 所在的项目目录。然后输入 mvnDebug clean install。如果一切设置正确,它应该会显示类似 "Listening for transport dt_socket at address: 8000".
的内容
回到IDEA,执行我们刚才做的mvnDebug配置。如果一切设置正确,它应该显示类似 "Connected to the target VM, address: 'localhost:8000', transport: 'socket'".
的内容
返回命令提示符,如果没有任何反应,请按某个键将其唤醒。
如果一切设置正确,IDEA 将在断点处停止,暂停 javac(Java 编译器)的执行。
关于注释处理的其他教程
- Annotation processing 101 - 作者:Hannes Dorfmann。
我正在尝试学习如何制作自定义注释处理器,但我一直在尝试调试它。
我已经设法 运行 调试模式下的 javac 编译器(使用 mvnDebug clean install)(使用带有注释处理器的其他项目),连接到它与 IntelliJ IDEA 并让它在注释处理器的断点处停止。
如果我们项目的某个包中有类似的东西,就像任何其他包一样class(例如,没有特殊配置或任何东西):
public class MyProcessor extends AbstractProcessor {...}
我们能否以某种方式将其作为注解处理器挂接到 maven 的构建过程中?所以它首先被编译,然后整个项目在注解处理器处于活动状态的情况下被编译。
此外,据我所知,注释处理器需要某种 META INF 文件,可以使用 google autoservices 注释处理器之类的东西生成。
所以也许是一个 Maven 构建过程,我们首先有 autoservices 运行,然后 class 扩展编译为注释处理器的 AbstractProcessor,最后用我们的代码编译整个项目自己的注释处理器处于活动状态(并且 javac 编译器处于调试模式)。
这是食谱。
旁注:我在某些情况下做得非常详细,请跳过您已经知道该怎么做的部分。
首先,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)
在 IDEA 中创建一个没有任何 Archetype 的 Maven 项目。然后在 src > main > java
中创建一些包
创建一个扩展 javax.annotation.processing.AbstractProcessor.
的 Class
插入一些最少的代码,使其正常工作。 (不要忘记 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(); } }
在同一个包中创建注释。
public @interface Factory { }
在项目中可能有一个目录src > test > java,在那里创建另一个与你的包同名的包较早创建。然后在其中创建一个名称以"Test"结尾的Class(例如:MyProcessorTest)。然后使用您之前创建的新注释类型 (@Factory) 注释此 class。
@Factory public class MyProcessorTest { }
现在,注释处理器要工作,它们必须在 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>
用
@AutoService(Processor.class)
注释我们的处理器Class。现在,我们必须在IDEA中设置远程调试器配置。为此,请转到 运行 > 编辑配置,单击左上角的绿色 + 按钮,select 遥控器。将其命名为 "mvnDebug",将主机设置为 localhost,将端口设置为 8000,按确定就可以了。
在处理器的 process 方法中设置一个断点。
打开 Windows 命令提示符,导航到 pom.xml 所在的项目目录。然后输入 mvnDebug clean install。如果一切设置正确,它应该会显示类似 "Listening for transport dt_socket at address: 8000".
的内容
回到IDEA,执行我们刚才做的mvnDebug配置。如果一切设置正确,它应该显示类似 "Connected to the target VM, address: 'localhost:8000', transport: 'socket'".
的内容
返回命令提示符,如果没有任何反应,请按某个键将其唤醒。
如果一切设置正确,IDEA 将在断点处停止,暂停 javac(Java 编译器)的执行。
关于注释处理的其他教程
- Annotation processing 101 - 作者:Hannes Dorfmann。