随着 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
中列出这些 jars范围。然后我添加一个 requires
我的指令 module-info.java
带有 jar 名称。
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?
你有两个选择:
- (更难)“分解”包的依赖关系。然而,如果您不熟悉图书馆的内部运作,这可能会很困难或不可能。
- (更容易)将两个 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/57878642/