随着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在这里。但是,这些库还没有任何模块信息。
module-info.java
rxjava
rxjavafx
为了解决这个问题,我读到我需要创建自动模块。据我了解,我需要将rxjavaand rxjavafxjars 重命名为一个简单的名称,然后在--module-path参数中列出jars 。然后requires,我module-info.java在jar名称中添加一条指令。
rxjavaand rxjavafxjars
--module-pat
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中,并将其添加为单个模块。不过,这似乎不是一个好的解决方案…
所以我的问题是:
注意:我尝试使用标准java/来运行它,javac它们会导致相同的问题。这也是我的Java版本:
java/
javac
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)
我是否正确使用新的模块系统?
是。你看到的是预期的行为,这是因为JPMS模块不允许拆分包。
如果你不熟悉术语“拆分包”,则它实际上意味着同一包的两个成员来自两个不同的模块。
例如: com.foo.A(来自moduleA.jar) com.foo.B(来自moduleB.jar)
我该怎么办?
你有两种选择:
希望rx最终会在将来的某个时候将其库更新为不包含拆分包。在此之前,我的建议是将两个jar一起捣成一个jar(选项2)。