包与 Java 9 中的自动模块冲突
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42358084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Package conflicts with automatic modules in Java 9
提问by flakes
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 rxjavaand rxjavafx
随着 Java 9 的临近,我认为将我的一些项目移植到 Java 9 是一个很好的学习练习。在我的一个项目中,我依赖于rxjava和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.
我想将此项目创建为命名模块。要做到这一点,我需要创建一个module-info.java
文件,我需要为指定的要求rxjava
,并rxjavafx
在这里。但是,这些库还没有任何模块信息。
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.
为了解决这个问题,我读到我需要创建 Automatic Modules。据我了解,我需要将rxjava
和rxjavafx
jars重命名为一个简单的名称,然后在--module-path
参数中列出 jars 。然后requires
我在我module-info.java
的 jar 名称中添加一个指令。
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:
我写了一个 gradle 任务来为我编辑 jar 名称,它似乎在大多数情况下都有效。它需要所有需要编译的 jars 并将它们重命名为不包含版本信息或斜线。然后将这些文件连接成一个:
单独的字符串:
tasks.withType(JavaCompile) {
delete { delete '/tmp/gradle' }
copy {
from configurations.compile + configurations.testCompile
into '/tmp/gradle'
rename '(.*)-[0-9]+\..*.jar', '.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:
自然地,这些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
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...
似乎解决此问题的唯一方法是将rxjava
和的内容重新打包rxjavafx
到单个 jar 中,并将其添加为单个模块。虽然这似乎不是一个好的解决方案......
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?
- 我是否正确使用了新的模块系统?
- 我能怎么办这个错误?和
- 这些依赖项是否会阻止我更新,还是应该等待 rx 更新它们的库?
Note: I've tried running this with standard java
/javac
and they cause the same issues. Also here is my java version:
注意:我试过用标准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)
采纳答案by Andy Guibert
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.
是的。您看到的是预期行为,这是因为 JPMS 模块不允许拆分包。
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)
例如:
com.foo.A(来自moduleA.jar)
com.foo.B(来自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?
这些依赖项是否会阻止我更新,还是应该等待 rx 更新它们的库?
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).
希望 rx 最终会更新他们的库,以便在未来的某个时候不会拆分包。在那之前,我的建议是将两个罐子一起粉碎成一个罐子(选项 2)。
回答by Rados?aw Osiński
I had simmiliar problem:
我有类似的问题:
error: module flyway.core reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and java.sql
error: module slf4j.api reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and java.sql
error: module hibernate.core reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and java.sql
.../src/main/java/module-info.java:1: error: module eu.com.x reads package javax.transaction.xa from both java.sql and jboss.transaction.api.1.2.spec
I could get rid of split packages compilation problem by checking my project transitive dependencies ("gradle dependencies" or "mvn dependency:tree" could be helpful) and excluding by code simmiliar to:
我可以通过检查我的项目传递依赖项(“gradle 依赖项”或“mvn 依赖项:树”可能会有所帮助)并通过类似于以下内容的代码排除来解决拆分包编译问题:
configurations.all {
exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.2_spec'
}
or
或者
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.10.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.2_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
No jar repackaging was needed im my problem. This problem have not occured on #JDK8. Probably excluding dependencies does not help in every project.
我的问题不需要 jar 重新包装。#JDK8 上未出现此问题。可能排除依赖项对每个项目都没有帮助。
回答by kamel2005
i have been facing the same issue with java.transaction.xa read package from both javaee and java.transaction.xa. And i fixed it by adding this line to my modul-info.java
我在 java.transaction.xa 从 javaee 和 java.transaction.xa 读取包时遇到了同样的问题。我通过将此行添加到我的 modul-info.java 来修复它
opens javax.transaction.xa;
It worked fine but a hint shown up saying the package javax.transaction.xa is empty or doesn't exists. however the source code compile correctly.
它工作正常,但提示显示包 javax.transaction.xa 为空或不存在。但是源代码编译正确。