包与 Java 9 中的自动模块冲突 [英] Package conflicts with automatic modules in Java 9

查看:49
本文介绍了包与 Java 9 中的自动模块冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着 Java 9 的临近,我认为将我的一些项目移植到 Java 9 是一个很好的学习练习.在我的一个项目中,我依赖于 rxjavarxjavafx

依赖项{编译'io.reactivex:rxjava:1.2.6'编译'io.reactivex:rxjavafx:1.0.0'...}

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

为了解决这个问题,我读到 我需要创建自动模块.据我了解,我需要将 rxjavarxjavafx jar 重命名为一个简单的名称,然后在 --module-path 参数.然后我在我的 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

似乎解决此问题的唯一方法是将 rxjavarxjavafx 的内容重新打包到一个 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)

<块引用>

我该怎么办这个错误?

您有两个选择:

  1. (更难)拆分"包依赖项.但是,如果您不熟悉库的内部工作原理,这可能会很困难或不可能
  2. (更简单)将两个 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:

  1. (harder) "unsplit" the package dependencies. However this could be difficult or impossible if you are not familiar with the inner workings of the library
  2. (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆