JDK9 自动模块和“拆分包”依赖关系

问题描述 投票:0回答:2

我正在将 java 项目转换为使用模块。我的一个模块依赖于

hamcrest
库,它需要两个 jar 文件
hamcrest.core
hamcrest.library
。这两个jar文件都有
org.hamcrest
包。因此,当我的模块想要将这两个 jar 视为自动模块时,它会失败,因为模块路径中的两个模块不能具有相同名称的包。我查了很多资料,在 stackoverflow 上找到了一些相关的东西。如果我不想重建这些依赖项,我似乎有两个合理的选择:

  1. 使用我的构建自动化工具(maven)将两个 jar 合并为一个 jar。
  2. 以某种方式告诉java编译器这两个jar应该被视为单个自动模块。

这是我的问题:

  • 这两个选项中的任何一个都可能吗?如果是的话,怎么办?
  • 还有更好的选择吗?

提前致谢

java maven java-9 hamcrest java-module
2个回答
6
投票

好吧,我终于成功解决了这个问题:

  1. 创建一个名为
    hamcrest-all
    的新 Maven 模块,并添加对
    hamcrest-core
    hamcrest-library
    的依赖项。
  2. maven-assembly-plugin
    添加到此模块,并将
    appendAssemblyId
    设置为 false。
  3. 从其他 Maven 模块中删除对
    hamcrest-core
    hamcrest-library
    的依赖,并添加对
    hamcrest-all
    的依赖。
  4. 在包含对
    hamcrest-core
    的依赖时排除
    hamcrest-library
    hamcrest-all

它实际上的作用是在为

hamcrest-core
创建的 jar 文件中解压
hamcrest-library
hamrest-all
。而且因为 JMPS 将每个 jar 文件视为一个模块,所以问题就消失了:)


0
投票

我对 Feri 的解决方案略有不同。

对我来说,我在多模块 Maven 项目中遇到了 3 个关于

maven-assembly-plugin
的问题。

首先,生成的jar不仅包含请求的依赖项,还包含传递依赖项。

其次,由于我不太明白的原因,

maven-assembly-plugin
将生成的
module-info.class
放入我的罐子中,这完全破坏了解决方案。

第三,IntelliJ 似乎不理解这个设置,并抱怨缺少模块。

前 2 个问题可以通过从

maven-assembly-plugin
切换到
maven-shade-plugin
来解决,如下所示:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.6.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <artifactSet>
                                <includes>
                                    <include>[group-id:artifact-id]</include>
                                    <include>[...]</include>
                                </includes>
                            </artifactSet>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

这会生成一个仅包含指定模块的 jar,并且没有

module-info.class

切换到

maven-shade-plugin
后,我们现在还可以解决第三个问题:
maven-shade-plugin
忽略
module-info.java
,所以我们现在可以创建一个仅由IntelliJ使用的
module-info.java

module hamcrest.all {
  requires transitively hamcrest-core;
  requires transitively hamcrest-library;
}
© www.soinside.com 2019 - 2024. All rights reserved.