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

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

问题描述

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

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'
    ...
}

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

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.

为了解决这个问题,我已经读过我需要创建自动模块。根据我的理解,我需要重命名 rxjava rxjavafx jars以获得一个简单的名称,然后列出罐子在 - module-path 参数中。然后我在我的 module-info.java 中使用jar名称添加 requires 指令。

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;
}

我为我编写了一个gradle任务来编辑jar名称,它出现了在大多数情况下工作。它需要编译所有的jar并将它们重命名为不包含version-info或slashes。然后将这些文件连接成分隔的字符串:

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(':')]
}

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

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

似乎解决这个问题的唯一方法是重新打包 rxjava 和<$的内容c $ c> rxjavafx 进入一个jar并将其添加为单个模块。这似乎不是一个好的解决方案......

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...

所以我的问题是:


  • 我是否正确使用新模块系统?

  • 我该怎么办?和

  • 这些依赖项是否阻止我更新,还是应该等待rx更新它们的库?

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

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?

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

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.

例如:

com.foo.A(来自moduleA.jar)

com.foo.B(来自moduleB.jar)

For example:
com.foo.A (from moduleA.jar)
com.foo.B (from moduleB.jar)


我该怎么办?这个错误?

What can I do about this error?

您有两种选择:


  1. (更难)unsplit包依赖项。但是,如果您不熟悉库的内部工作原理,这可能很难或不可能。

  2. (更容易)将两个罐子组合成一个罐子(因此是一个自动模块)你上面提到过。我同意这不是一个好的解决方案,但首先拆分包装通常也不是一个好主意。




这些依赖项是否阻止我更新,或者我应该等待rx更新它们的库?

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

希望rx最终会更新他们的libs,以便在将来的某个时候没有拆分包。在此之前,我的建议是将两个罐子一起粉碎成一个罐子(选项#2)。

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天全站免登陆