java - 包与 Java 9 中的自动模块冲突

标签 java compiler-errors java-9 java-module java-platform-module-system

随着 Java 9 的临近,我认为将我的一些项目移植到 Java 9 将是一个很好的学习练习。在我的一个项目中,我有 rxjava 的依赖项。和 rxjavafx

dependencies {
    compile 'io.reactivex:rxjava:1.2.6'
    compile 'io.reactivex:rxjavafx:1.0.0'
    ...
}

我想将此项目创建为命名模块。为此,我需要创建一个 module-info.java 文件,并且需要在此处指定 rxjava 和 rxjavafx 的要求。但是,这些库还没有任何模块信息。

为了解决这个问题,我读过 I need to create Automatic Modules 。据我了解,我需要将 rxjava 和 rxjavafx jar 重命名为简单的名称,然后在 --module-path 参数中列出 jar。然后,我在 module-info.java 中添加包含 jar 名称的 requires 指令。

module com.foo.bar {
    requires rxjavafx;
    requires rxjava;
}

我编写了一个 gradle 任务来为我编辑 jar 名称,它似乎在大多数情况下都有效。它获取所有需要编译的 jar 并将其重命名为不包含版本信息或斜杠。然后,这些文件将连接成 : 分隔的字符串:

tasks.withType(JavaCompile) {
    delete { delete '/tmp/gradle' }
    copy {
        from configurations.compile + configurations.testCompile
        into '/tmp/gradle'
        rename '(.*)-[0-9]+\\..*.jar', '$1.jar'
        rename { String fileName -> fileName.replace("-", "") }
    }
    options.compilerArgs += ['--module-path', fileTree(dir: '/tmp/gradle', include: '*.jar').getFiles().join(':')]
}

当然,rx 库共享一些包名称...但这会导致编译器吐出错误,例如:

error: module  reads package rx.subscriptions from both rxjava and rxjavafx
error: module  reads package rx.schedulers from both rxjava and rxjavafx
error: module  reads package rx.observables from both rxjava and rxjavafx
error: module rxjava reads package rx.subscriptions from both rxjavafx and rxjava
error: module rxjava reads package rx.schedulers from both rxjavafx and rxjava
error: module rxjava reads package rx.observables from both rxjavafx and rxjava
error: module rxjavafx reads package rx.subscriptions from both rxjava and rxjavafx
error: module rxjavafx reads package rx.schedulers from both rxjava and rxjavafx
error: module rxjavafx reads package rx.observables from both rxjava and rxjavafx

解决此问题的唯一方法似乎是将 rxjava 和 rxjavafx 的内容重新打包到单个 jar 中并将其添加为单个模块。但这似乎不是一个好的解决方案......

所以我的问题是:

  • 我是否正确使用了新的模块系统?
  • 对于此错误我该怎么办?和
  • 这些依赖项是否会阻止我更新,或者我应该等待 rx 更新其库?
<小时/>

注意:我尝试使用标准 java/javac 运行此程序,它们会导致相同的问题。这也是我的java版本:

java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+140)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+140, mixed mode)

最佳答案

Am I using the new module system correctly?

是的。您所看到的是预期行为,这是因为 JPMS 模块不允许拆分包。

如果您不熟悉术语“拆分包”,它本质上意味着来自两个不同模块的同一包的两个成员。

例如:
com.foo.A(来自 moduleA.jar)
com.foo.B(来自 moduleB.jar)

What can I do about this error?

您有两个选择:

  1. (更难)“分解”包依赖项。但是,如果您不熟悉库的内部运作方式,这可能会很困难或不可能
  2. (更简单)将两个 jar 合并成一个 jar (因此是一个自动模块),如上所述。我同意这不是一个“好的”解决方案,但是首先拆分包通常也不是一个好主意。

Do these dependencies prevent me from updating, or should I just wait for rx to update their libs?

希望 rx 最终能够更新他们的库,以便在将来的某个时候不再有拆分包。在那之前,我的建议是将两个 jar 一起粉碎成一个 jar (选项#2)。

关于java - 包与 Java 9 中的自动模块冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45744134/

相关文章:

java - 什么是 sjavac,它适用于谁以及如何使用它?

java - 为什么我的围绕另一个点旋转一个点的方法不起作用?

java - 使用 Quarkus 连接到 Azure Key Vault

c - 未知类型名称 C 与 C++

c++ - 错误 - 不完整类型/前向声明的无效使用

C++ 列表迭代器无法初始化

java - 如何使用外部 jar 运行 hadoop?

java - 在android中查找多边形中的点

java - 使用 Jetty 9 作为 Java 9 模块给出 ClassNotFoundException

java - 如何解决 Java 9 中的拆分包问题