在 Maven 插件中,如何从依赖项访问文件?
In a Maven plugin, how can I access files from a dependency?
背景:我正在尝试将特定领域语言的编译器挂接到 Maven 中。 DSL 被编译为 Java 源代码,所以我的想法是编写一个在生成源阶段执行的 Mojo。编译器目前作为 Gradle 插件实现,无法处理具有依赖关系的多个项目,在尝试支持项目时,我遇到了 Gradle 中的问题。我现在正试图了解 Maven 是否能以更好的方式处理这种情况。 Gradle的问题与本题无关。
我的 DSL 有像 Java 这样的包映射到相同的 Java 包。对于项目(称为“模块”,AFAIK,如果它们是反应堆构建的一部分)也应该如此。在那种情况下,对于每个项目,DSL 源被编译为 Java 源代码,以及元数据(每个编译 class 一个 JSON 文件)。当项目 A 依赖于 B 时,A 的 DSL 编译过程需要来自 B 的元数据文件。该元数据应与生成和编译的 Java 代码一起作为资源打包到 JAR 文件中,以及可能是手写和编译的 Java 代码。
在 Maven 中,我可以将当前的 MavenProject 注入到 Mojo 中。我可以向 MavenProject 询问它的依赖关系,但我似乎只得到元数据,比如依赖关系的 Maven 坐标。我不明白如何从依赖项访问文件。这样做需要什么?
我还不明白是否必须区分依赖项是来自工件存储库的 JAR 还是反应堆构建中的另一个模块。这样做的原因显然是,在反应器构建中,依赖项不需要经历完整的 Maven 生命周期直到“安装”:假设项目 A 依赖于项目 B,并且我 运行父级中的“mvn generate-sources”。然后是项目 B 中的 DSL 编译器 运行s,然后是项目 A 中的 运行s。但是,B 的构建过程在生成源后停止了,因此对于 A、B 的 DSL 编译器看起来与存储库中的工件非常不同——从没有 JAR 文件这一事实开始。我必须做出这种区分(在反应器依赖性和存储库依赖性之间)是否正确?如果是这样,我如何获得必要的信息?是否有关于如何做到这一点的最佳实践?
我设法通过将“依赖项解析器”注入我的 Mojo(它是 RepositorySystem 的一个薄包装)以及后者的会话来访问依赖项:
@Component
private ProjectDependenciesResolver projectDependenciesResolver;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
private RepositorySystemSession repoSession;
我可以使用它们来获取依赖项:
DefaultDependencyResolutionRequest request = new DefaultDependencyResolutionRequest(project, repoSession);
DependencyResolutionResult result = projectDependenciesResolver.resolve(request);
结果包含作为 File 对象的依赖项,它可以指向 .m2 文件夹中的 JAR(用于存储库依赖项),一个刚刚构建的 JAR 文件(用于构建足够“高”阶段时的反应器依赖项),一个充满 class 文件的文件夹(用于在尚未发生 JAR 打包的“较低”阶段构建时的反应器依赖项),或者根本不存在(用于构建“非常低”时的反应器依赖项阶段)。
这对我来说已经足够了。我必须根据我得到的是 JAR 文件、文件夹还是什么都没有来区分(应该很简单),而且我必须处理这样一个事实,即在向 X 阶段构建时,反应器依赖项也会构建最多只有 X,所以我需要的文件可能会丢失。
背景:我正在尝试将特定领域语言的编译器挂接到 Maven 中。 DSL 被编译为 Java 源代码,所以我的想法是编写一个在生成源阶段执行的 Mojo。编译器目前作为 Gradle 插件实现,无法处理具有依赖关系的多个项目,在尝试支持项目时,我遇到了 Gradle 中的问题。我现在正试图了解 Maven 是否能以更好的方式处理这种情况。 Gradle的问题与本题无关。
我的 DSL 有像 Java 这样的包映射到相同的 Java 包。对于项目(称为“模块”,AFAIK,如果它们是反应堆构建的一部分)也应该如此。在那种情况下,对于每个项目,DSL 源被编译为 Java 源代码,以及元数据(每个编译 class 一个 JSON 文件)。当项目 A 依赖于 B 时,A 的 DSL 编译过程需要来自 B 的元数据文件。该元数据应与生成和编译的 Java 代码一起作为资源打包到 JAR 文件中,以及可能是手写和编译的 Java 代码。
在 Maven 中,我可以将当前的 MavenProject 注入到 Mojo 中。我可以向 MavenProject 询问它的依赖关系,但我似乎只得到元数据,比如依赖关系的 Maven 坐标。我不明白如何从依赖项访问文件。这样做需要什么?
我还不明白是否必须区分依赖项是来自工件存储库的 JAR 还是反应堆构建中的另一个模块。这样做的原因显然是,在反应器构建中,依赖项不需要经历完整的 Maven 生命周期直到“安装”:假设项目 A 依赖于项目 B,并且我 运行父级中的“mvn generate-sources”。然后是项目 B 中的 DSL 编译器 运行s,然后是项目 A 中的 运行s。但是,B 的构建过程在生成源后停止了,因此对于 A、B 的 DSL 编译器看起来与存储库中的工件非常不同——从没有 JAR 文件这一事实开始。我必须做出这种区分(在反应器依赖性和存储库依赖性之间)是否正确?如果是这样,我如何获得必要的信息?是否有关于如何做到这一点的最佳实践?
我设法通过将“依赖项解析器”注入我的 Mojo(它是 RepositorySystem 的一个薄包装)以及后者的会话来访问依赖项:
@Component
private ProjectDependenciesResolver projectDependenciesResolver;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
private RepositorySystemSession repoSession;
我可以使用它们来获取依赖项:
DefaultDependencyResolutionRequest request = new DefaultDependencyResolutionRequest(project, repoSession);
DependencyResolutionResult result = projectDependenciesResolver.resolve(request);
结果包含作为 File 对象的依赖项,它可以指向 .m2 文件夹中的 JAR(用于存储库依赖项),一个刚刚构建的 JAR 文件(用于构建足够“高”阶段时的反应器依赖项),一个充满 class 文件的文件夹(用于在尚未发生 JAR 打包的“较低”阶段构建时的反应器依赖项),或者根本不存在(用于构建“非常低”时的反应器依赖项阶段)。
这对我来说已经足够了。我必须根据我得到的是 JAR 文件、文件夹还是什么都没有来区分(应该很简单),而且我必须处理这样一个事实,即在向 X 阶段构建时,反应器依赖项也会构建最多只有 X,所以我需要的文件可能会丢失。