【发布时间】:2020-07-27 14:02:59
【问题描述】:
背景:我正在尝试将特定领域语言的编译器挂接到 Maven 中。 DSL 被编译为 Java 源代码,所以我的想法是编写一个在生成源阶段执行的 Mojo。编译器目前是作为 Gradle 插件实现的,无法处理具有依赖关系的多个项目,并且在尝试支持项目时,我在 Gradle 中遇到了问题。我现在试图了解 Maven 是否以更好的方式处理这种情况。 Gradle 的问题与这个问题无关。
我的 DSL 有像 Java 这样的包,它们被映射到相同的 Java 包。对于项目(称为“模块”,AFAIK,如果它们是反应堆构建的一部分)也应该如此。在这种情况下,对于每个项目,DSL 源都被编译为 Java 源代码以及元数据(每个编译类的 JSON 文件)。当项目 A 依赖于 B 时,A 的 DSL 编译过程需要来自 B 的元数据文件。该元数据应作为资源与生成和编译的 Java 代码一起打包到 JAR 文件中,可能还需要手动打包。编写和编译的 Java 代码。
在 Maven 中,我可以将当前的 MavenProject 注入 Mojo。我可以向 MavenProject 询问其依赖项,但我似乎只获得了元数据,例如依赖项的 Maven 坐标。我不明白如何从依赖项中访问文件。这样做有什么必要?
我也不明白是否必须区分依赖项是来自工件存储库的 JAR 还是反应器构建中的另一个模块。原因是,显然,在反应堆构建中,依赖项不需要经历整个 Maven 生命周期直到“安装”:假设项目 A 依赖于项目 B,我运行“mvn generate-来源”在父级。然后 DSL 编译器在项目 B 中运行,然后在项目 A 中运行。但是,在 generate-sources 之后,B 的构建过程已经停止,因此对于 A 的 DSL 编译器,B 看起来与存储库中的工件非常不同 - - 从没有 JAR 文件的事实开始。我必须做出这种区分(反应堆依赖项和存储库依赖项之间)是否正确?如果是这样,我如何获得必要的信息?有没有关于如何做到这一点的最佳实践?
【问题讨论】:
-
您能否更详细地解释为什么您需要运行代码生成的项目的依赖项?
-
如果 A 依赖于 B,那么 B 中的 DSL 文件包含我需要编译 A 中的 DSL 文件的类型信息。B 的编译器将它们从我的 DSL 源文件提取到元数据文件(JSON )。在编译 A 时,我需要访问那些 JSON 文件。
-
生成的Java文件中不是不存在这些类型信息吗?你能举个具体的例子,它的样子和真正的问题是什么?
-
它们无法在 Java 文件中表示,因为我的 DSL 具有类似于数组的类型,其中大小是静态恒定的并且是类型的一部分。 Java 没有这样的类型。它有例如int[] 但不是 int[5] 作为类型。除此之外,即使在 Java 类中编码了类型信息,问题仍然存在:编译 A 时如何访问 Java 类? WRT“真正的问题”——我已经说过了。在编译多项目源时,访问已编译的依赖项是正常的步骤;请注意“javac”工具的作用完全相同,原因相同。
-
您可以将您的插件配置为具有特定的依赖解析(maven.apache.org/developers/mojo-api-specification.html 参见
requiresDependencyResolution),它可以让您访问真正的 jar。但是,如果您需要从其他模块访问 JSON 文件,这是一种资源,通常会被打包到结果 jar 中,并且可以通过类路径访问。错过一个:maven.apache.org/plugin-tools/maven-plugin-tools-annotations/…
标签: maven plugins dependencies