包与 Java 9 中的自动模块冲突 [英] Package conflicts with automatic modules in Java 9
问题描述
随着 Java 9 的临近,我认为将我的一些项目移植到 Java 9 是一个很好的学习练习.在我的一个项目中,我依赖于 rxjava 和 rxjavafx
依赖项{编译'io.reactivex:rxjava:1.2.6'编译'io.reactivex:rxjavafx:1.0.0'...}
我想将此项目创建为命名模块.为此,我需要创建一个 module-info.java
文件,并且需要在此处指定 rxjava
和 rxjavafx
的要求.但是,这些库还没有任何模块信息.
为了解决这个问题,我读到 我需要创建自动模块.据我了解,我需要将 rxjava
和 rxjavafx
jar 重命名为一个简单的名称,然后在 --module-path中列出这些 jar代码> 参数.然后我在我的
module-info.java
中添加一个 requires
指令和 jar 名称.
module com.foo.bar {需要 rxjavafx;需要 rxjava;}
我写了一个 gradle 任务来为我编辑 jar 名称,它似乎在大多数情况下都有效.它需要所有需要编译的 jars 并将它们重命名为不包含版本信息或斜线.然后将这些文件连接成一个 :
分隔的字符串:
tasks.withType(JavaCompile) {删除 { 删除 '/tmp/gradle' }复制 {来自configuration.compile +configuration.testCompile进入'/tmp/gradle'重命名 '(.*)-[0-9]+\..*.jar', '$1.jar'重命名 { 字符串文件名 ->文件名.replace("-", "") }}options.compilerArgs += ['--module-path', fileTree(dir: '/tmp/gradle', include: '*.jar').getFiles().join(':')]}
自然地,rx
库共享它们的一些包名...然而这会导致编译器回吐错误,例如:
错误:模块从 rxjava 和 rxjavafx 读取包 rx.subscriptions错误:模块从 rxjava 和 rxjavafx 读取包 rx.schedulers错误:模块从 rxjava 和 rxjavafx 读取包 rx.observables错误:模块 rxjava 从 rxjavafx 和 rxjava 读取包 rx.subscriptions错误:模块 rxjava 从 rxjavafx 和 rxjava 读取包 rx.schedulers错误:模块 rxjava 从 rxjavafx 和 rxjava 读取包 rx.observables错误:模块 rxjavafx 从 rxjava 和 rxjavafx 读取包 rx.subscriptions错误:模块 rxjavafx 从 rxjava 和 rxjavafx 读取包 rx.schedulers错误:模块 rxjavafx 从 rxjava 和 rxjavafx 读取包 rx.observables
似乎解决此问题的唯一方法是将 rxjava
和 rxjavafx
的内容重新打包到一个 jar 中,并将其添加为单个模块.虽然这似乎不是一个好的解决方案...
所以我的问题是:
- 我是否正确使用了新的模块系统?
- 对于这个错误,我该怎么办?和
- 这些依赖项是否会阻止我更新,还是我应该等待 rx 更新它们的库?
注意:我试过用标准的 java
/javac
运行它,它们导致了同样的问题.这也是我的 Java 版本:
java 版本9-ea"Java(TM) SE 运行时环境(构建 9-ea+140)Java HotSpot(TM) 64 位服务器 VM(构建 9-ea+140,混合模式)
我是否正确使用了新的模块系统?
是的.您看到的是预期行为,这是因为 JPMS 模块不允许拆分包.
如果您不熟悉术语拆分包",它本质上是指来自两个不同模块的同一包的两个成员.
例如:
com.foo.A(来自moduleA.jar)
com.foo.B(来自 moduleB.jar)
我该怎么办这个错误?
您有两个选择:
- (更难)拆分"包依赖项.但是,如果您不熟悉库的内部工作原理,这可能会很困难或不可能
- (更简单)将两个 jar 组合成一个 jar(因此是一个自动模块),如上所述.我同意这不是一个好"的解决方案,但首先拆分包通常也不是一个好主意.
<块引用>
这些依赖是否会阻止我更新,还是我应该等待 rx 更新它们的库?
希望 rx 最终会更新他们的库,以便在未来的某个时候不会拆分包.在那之前,我的建议是将两个罐子一起粉碎成一个罐子(选项 #2).
With Java 9 on the close horizon I thought it would be a good learning exercise to port some of my projects over to Java 9. In one of my projects I have dependencies for rxjava and rxjavafx
dependencies {
compile 'io.reactivex:rxjava:1.2.6'
compile 'io.reactivex:rxjavafx:1.0.0'
...
}
I want to create this project as a named-module. To do this I need to create a module-info.java
file and I need to specify the requirements for rxjava
and rxjavafx
here. However, these libs don't have any module info yet.
In order to work around this I've read that I need to create Automatic Modules. From what I understand, I need to rename the rxjava
and rxjavafx
jars to have a simple name and then list the jars in the --module-path
parameter. I then add a requires
directive in my module-info.java
with the jar names.
module com.foo.bar {
requires rxjavafx;
requires rxjava;
}
I wrote a gradle task to edit the jar names for me, and it appears to be working in most cases. It takes all the jars that need to be compiled and renames them to not include version-info or slashes. The files are then concatenated into a :
separated string:
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(':')]
}
Naturally the rx
libraries share some of their package names... this however causes the compiler to spit back errors such as:
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
It seems like the only way to get around this issue would be to re-package the contents of rxjava
and rxjavafx
into a single jar and add that as a single module. This doesn't seem like a good solution though...
So my questions are:
- Am I using the new module system correctly?
- What can I do about this error? and
- Do these dependencies prevent me from updating, or should I just wait for rx to update their libs?
Note: I've tried running this with standard java
/javac
and they cause the same issues. Also here is my java version:
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?
Yes. What you are seeing is intended behavior, and this is because JPMS modules do not allow split packages.
In case you are not familiar with the term "split packages" it essentially means two members of the same package coming from two different modules.
For example:
com.foo.A (from moduleA.jar)
com.foo.B (from moduleB.jar)
What can I do about this error?
You have two options:
- (harder) "unsplit" the package dependencies. However this could be difficult or impossible if you are not familiar with the inner workings of the library
- (easier) combine the two jars into a single jar (and therefore a single automatic module) as you mentioned above. I agree that it is not a "good" solution, but having split packages in the first place is generally not a good idea either.
Do these dependencies prevent me from updating, or should I just wait for rx to update their libs?
Hopefully rx will eventually update their libs to not have split packages at some point in the future. Until then, my recommendation would be to just smash the two jars together into a single jar (option #2).
这篇关于包与 Java 9 中的自动模块冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!