使用 Maven 构建具有非模块化依赖项的 JDK 9 项目需要什么

What do I need to build JDK 9 project with non-modular dependencies using Maven

我有一个简单的 Java 9 SE 项目,它依赖于一个非模块化项目(为此示例选择 Weld SE),我正在尝试使用 Maven 构建它 (clean install) .为了让 Java 9 生效,我添加了 module-info.java。最初,此文件仅包含模块名称,没有 requires 个公式。

请记住,我唯一的依赖项不是模块化项目,因此我假设 Maven 将放入类路径(而不是模块路径),因此它将最终出现在 unnamed module 中,如中所述State of the modular system.

现在,我的 Maven 版本是 3.3.9,我知道我需要在版本 3.6 中使用 Maven 编译器插件,因为 described here 当然我已经下载了 JDK 9 EA 构建jigsaw 并设置 Maven 来使用它。

如果我在没有 module-info.java 的情况下构建我的项目,一切正常,内容被添加到类路径并且构建成功。我想 Maven 只是坚持使用旧方法,只要您省略该文件即可。

但是 with module-info.java 构建它告诉我在类路径中找不到依赖项中的 类。所以我 运行 Maven 处于调试模式(使用 -X)并且确实 - 所有 jar 都在模块路径下并且类路径是空的。这实际上意味着我所有的依赖项都被 t运行 转移到 automatic modules 中,我需要在 module-info.java.

中声明它们

一旦我声明 automatic module requirements(link 到项目的 module-info),我就可以在 JDK 9[=62 上构建它=].但这有点混乱 - 我唯一的 pom.xml 依赖于 weld-se-core,但我的 module-info 需要我声明 很多更多的编译要求 通过。

这里是一个整体GitHub project,所有这些都可以观察到。

所以我的问题是:

  1. 如果我知道一些工件没有模块化,我可以告诉 Maven 将它们放在类路径中吗?这样我就可以避免 automatic module 和声明它们的需要?
  2. 如果我坚持使用 automatic module,我可以告诉 Maven 以某种方式 t运行sitively 允许我的依赖项需要引入的任何东西吗?例如。 Weld、CDI等其他部分API等
  3. 真正的原因是什么,为什么我需要声明我的项目 requires 模块,我 不直接使用?例如。 weld.environment.common

如果您指定 module-info.java 文件,则需要声明所有 java 模块,但 java.base 除外,因为您现在正在使用 jigsaw。

使用 mvn dependency:tree 可以帮助您填充它,但您不需要在 Java 9.

中使用 module-info.java

包括最近的一些更新,我会尝试并回答这个问题。

UPDATE

假设从问题和评论中,您已经知道 automatic modules 并将所有模块依赖项放在模块路径上。

Can I tell Maven to put some artifacts on classpath if I know they are not modularized? So that I can avoid the automatic module and the need to declare them?

对于在 maven pom <dependencies> 中指定的工件以及那些也未包含在当前模块的 module-info.java 中的工件,最终将以以下形式从类路径中访问一个 unnamed module.

If I stick with automatic module, can I tell Maven to somehow transitively allow anything my dependency needs to bring in? E.g. other parts of Weld, CDI API etc.

No,因为自动模块不包含显式声明的module-info.java,所以没有这种定义方式 用于当前模块可能需要的任何传递依赖。

从我的 中可以看出,模块在编译时需要的 dependency:tree 中详述的任何 Maven 传递依赖项都必须使用 requires 在当前项目的module-info

What is the actual reason, why I need to state, that my project requires modules, which I do not use directly? E.g. weld.environment.common**

  • 您不需要为您的模块在编译或运行时不需要的模块指定requires

  • 如果项目在运行时不需要但在编译时需要依赖项,则需要确保使用 [= 定义此类模块59=] 在你的声明中。

    我现在最好也采用类似的方法,如对 should I keep or remove declared dependencies that are also transitive dependencies?

    的回答中所述

我认为这可能有助于告诉 maven 使用 java 9 :

    <build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>9</source>
                <target>9</target>
            </configuration>
        </plugin>
    </plugins>
</build>