在 Eclipse 中调试注释处理器

Posted

技术标签:

【中文标题】在 Eclipse 中调试注释处理器【英文标题】:Debugging Annotation processors in eclipse 【发布时间】:2014-02-21 00:47:23 【问题描述】:

我正在编写一个简单的注释处理器并尝试使用 eclipse 对其进行调试。我为注解处理器创建了一个新项目,并根据需要在 META-INF 下配置了 javax.annotation.processing.Processor,它可以很好地处理注解。

然后,我添加了更多代码并尝试调试,但始终无法在注释处理器中添加的断点处停止执行。我正在使用 ant 进行编译,并且正在使用以下 ANT 选项。

export ANT_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"

触发 ant build 后,我创建了一个远程调试配置,调试器启动正常。 Ant 构建也成功启动。但是执行永远不会在注释处理器中添加的任何断点处停止。

【问题讨论】:

【参考方案1】:

这是我刚刚遇到的一个问题,eclipse插件解决方案对我来说似乎超级麻烦。我找到了一个更简单的解决方案,使用 javax.tools.JavaCompiler 来调用编译过程。使用下面的代码,您可以在 Eclipse 中右键单击 > Debug As > JUnit Test 并直接从那里调试您的注释处理器

   @Test
   public void runAnnoationProcessor() throws Exception 
      String source = "my.project/src";

      Iterable<JavaFileObject> files = getSourceFiles(source);

      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

      CompilationTask task = compiler.getTask(new PrintWriter(System.out), null, null, null, null, files);
      task.setProcessors(Arrays.asList(new MyAnnotationProcessorClass()));

      task.call();
   

   private Iterable<JavaFileObject> getSourceFiles(String p_path) throws Exception 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
     StandardJavaFileManager files = compiler.getStandardFileManager(null, null, null);

     files.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(new File(p_path)));

     Set<Kind> fileKinds = Collections.singleton(Kind.SOURCE);
     return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true);
   

【讨论】:

谢谢!我不得不将静态源变量替换为 System.getProperty("user.dir") 并且这很顺利。【参考方案2】:

这个问题已经发布了 6 年多了,然而,我现在遇到了同样的问题,仍然无法在互联网上找到一个好的答案。

我终于能够制定出一个很好的设置,让我可以开发一个注释处理器,在另一个项目的编译中使用它,并根据需要进行调试。

设置是这样的:

    在使用 GAV 的项目中开发的注释处理器:

    <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version>

    在注释处理器 POM 文件中,我指定了以下内容:

    <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>$maven.compiler.plugin.version</version> <configuration> <compilerArgument>-proc:none</compilerArgument> <source>$java.source.version</source> <target>$java.source.version</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>

    注意&lt;compilerArgument&gt;-proc:none&lt;/compilerArgument&gt; 规范。

    在使用annotation-processor的项目中,在项目编译时使用。 IE。注释处理器在编译器执行期间被调用,javac。我发现为了在直接运行javac 时调试注释处理器的执行,我可以使用以下命令行:

    javac -J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044 -d target/classes -proc:only -processor infra.annotation.CustomizationAnnotationProcessor -cp ../annotation-processor /target/annotation-processor-1.0-SNAPSHOT.jar src\main\java\org\digital\annotationtest\MyTestClass.java

    注意javac 命令行中的suspend=y 部分。这告诉 JVM 暂停执行,直到调试器附加到它为止。

    在这种情况下,我可以通过启动远程 Java 应用程序调试配置来启动 eclipse 调试器。将其配置为使用注释处理器项目,并附加到本地主机和端口 1044 上的进程。这允许您调试注释处理器代码。如果在initprocess 方法中设置断点,调试器将中断。

    为了在使用 Maven 编译时启用相同的调试体验,我将 POM 文件设置如下:

      向使用注释处理器的 POM 添加依赖项: <dependency> <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version> </dependency> 在使用注释处理器的同一项目中定义以下内容:

    <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>$maven.compiler.plugin.version</version> <configuration> <source>1.8</source> <target>1.8</target> <fork>true</fork> <compilerArgs> <compilerArg>-J-verbose</compilerArg> <compilerArg>$enableDebugAnnotationCompilerArg</compilerArg> </compilerArgs> <forceJavacCompilerUse>true</forceJavacCompilerUse> <annotationProcessorPaths> <annotationProcessorPath> <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version> </annotationProcessorPath> </annotationProcessorPaths> <annotationProcessors> <annotationProcessor>infra.annotation.CustomizationAnnotationProcessor</annotationProcessor> </annotationProcessors> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>debugAnnotation</id> <properties> <enableDebugAnnotationCompilerArg>-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044</enableDebugAnnotationCompilerArg> </properties> </profile> </profiles>

    注意&lt;fork&gt;true&lt;/fork&gt;的使用, 和&lt;compilerArg&gt;$enableDebugAnnotationCompilerArg&lt;/compilerArg&gt;。 另外,请注意debugAnnotation 的配置文件定义和 &lt;enableDebugAnnotationCompilerArg&gt; 属性。 这允许我们启动注释处理器的调试会话 通过运行 mvn -P debugAnnotation package 并将 eclipse 调试器附加到编译器 处理方式与上面4中描述的相同。

【讨论】:

【参考方案3】:

最简单的方法是创建一个 eclipse 插件,然后直接从 eclipse 中调试它。 听起来要困难得多 - 这个:https://www.youtube.com/watch?v=PjUaHkUsgzo 是 youtube 中的 7 分钟指南,可以帮助您入门。

【讨论】:

以上是关于在 Eclipse 中调试注释处理器的主要内容,如果未能解决你的问题,请参考以下文章

你如何使用intellij调试java注释处理器?

使用 kapt 和 gradle 时无法调试注释处理器

注释处理器 org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor 支持的源版本 RELEASE_6 低于 sour

为啥 Eclipse 不编译 APT 生成的类?

Eclipse怎么注释代码

Eclipse调试程序时出现注释显示乱码该怎么办