在eclipse中调试注解处理器

15
我正在编写一个简单的注解处理器,并尝试使用eclipse进行调试。我为注解处理器创建了一个新项目,并根据需要在META-INF下配置javax.annotation.processing.Processor,它可以很好地处理注解。
然后,我添加了一些代码并尝试进行调试,但是无法使执行停止在注解处理器中添加的断点处。我正在使用ant编译,并使用以下ANT选项:
export ANT_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"
触发ant构建后,我创建了一个远程调试配置文件,调试器也成功启动,ant构建也顺利开始了。但是执行永远不会停在注解处理器中添加的任何断点处。
3个回答

27

我刚遇到了这个问题,而且对于使用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"),这一切都没有问题。 - Anjil Dhamala

4

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

我终于成功地找到了一个好的设置,可以让我开发注解处理器,将其用于另一个项目的编译,并在需要时进行调试。

设置如下:

  1. 在使用GAV开发的项目中,开发了一个注解处理器:

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

  2. 在注解处理器的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>

    注意 <compilerArgument>-proc:none</compilerArgument> 的设置。

  3. 在使用注解处理器的项目中,在编译项目时使用该处理器。也就是说,在执行编译器 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 在调试器连接到它之前暂停执行。

  4. 在这种情况下,可以通过启动远程 Java 应用程序调试配置来启动 Eclipse 调试器。将其配置为使用注解处理器项目,并在本地主机上的端口 1044 上附加到该进程。这样就可以调试注解处理器代码。如果在 initprocess 方法中设置了断点,则调试器会中断执行。

  5. 为了使使用 Maven 编译时具有相同的调试体验,我设置了 POM 文件如下:

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

    <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


我也想到了同样的“-J-agentlib:…”的想法,但请注意,如果我将该选项放在“javac”“arg文件”中(即javac @argfile.txt),我无法使其工作。显然,任何“-J”选项都需要直接出现在“javac”命令行上(即javac -J-agentlib:… @argfile.txt)。 - Nathaniel Mishkin

2

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


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