用于读取应用程序 类 并生成 java 的 Maven mojo

maven mojo for reading app classes and generating java

我想编写一个 Maven 插件,它将在构建时探索我的应用程序的类路径,搜索带有特定注释的 类,并为这些 java 代码添加实用程序 类,应该在应用程序的 JAR 中编译。

所以我写了一个mojo,继承自AbstractMojo,项目通过:

@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;

我有大部分代码,我的 mojo 确实可以执行,但我在正确的构建阶段插入我的 mojo 时遇到问题。

如果我这样插:

@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES,
      requiresDependencyResolution = ResolutionScope.COMPILE)

然后我生成的 java 代码被编译到 JAR 文件中。

请注意,我使用 project.addCompileSourceRoot 注册输出文件夹。

但这对我来说还不够,因为构建还为时过早:我无法读取类路径并从我的项目中找到 类。我认为它们还没有编译。

我这样搜索 类:

        final List<URL> urls = List.ofAll(project.getCompileClasspathElements())
                .map(element -> Try.of(() -> new File(element).toURI().toURL()).get());
        final URLClassLoader classLoader = new URLClassLoader(urls.toJavaList().toArray(new URL[0]), Thread.currentThread().getContextClassLoader());
        final Set<Class<?>> entities = HashSet.ofAll(new Reflections(classLoader).getTypesAnnotatedWith(MyAnnotation.class));

(我使用的是 vavr 但无论如何你都能理解要点)

所以,通过在 GENERATE_SOURCES 阶段插入我的代码,这段代码不起作用,我没有找到任何 类.

但是,如果我在 PROCESS_CLASSES 阶段插入魔力:

@Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES,
    requiresDependencyResolution = ResolutionScope.COMPILE)

然后找到我的 类,我可以从应用程序访问其余代码,但是尽管使用了 addCompileSourceRoot,但我生成的代码没有被考虑在构建中。

如何让这两个功能同时工作:能够从应用程序的其余部分探索代码能够生成将与其余部分一起编译的代码罐子?

我想可能的答案是 "you can't",但据我所知,querydsl and immmutables 正在这样做(我尝试阅读他们的源代码但找不到相关代码)。

所以@khmarbaise 是对的,我想要的不是 maven mojo,而是 maven 注释处理器。

我发现 this walkthrough was very helpful in creating one, and also this Whosebug answer 派上用场了。