当前位置: 首页 > 知识库问答 >
问题:

包与Java 9中的自动模块冲突

公良理
2023-03-14

随着Java9的临近,我认为将我的一些项目移植到Java9将是一个很好的学习练习。在我的一个项目中,我对rxjava和rxjavafx有依赖关系

dependencies {
    compile 'io.reactivex:rxjava:1.2.6'
    compile 'io.reactivex:rxjavafx:1.0.0'
    ...
}

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

为了解决这个问题,我读到我需要创建自动模块。据我所知,我需要重命名rxjavarxjavafxjar,使其具有一个简单的名称,然后在--module path参数中列出jar。然后在我的模块信息中添加requires指令。java和jar名称。

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

似乎解决这个问题的唯一方法是将rxjavarxjavafx的内容重新打包到一个jar中,并将其作为一个模块添加。但这似乎不是一个好的解决方案。。。

因此,我的问题是:

  • 我是否正确使用新模块系统
  • 对此错误我能做些什么?和
  • 这些依赖关系是否阻止我更新,或者我应该等待rx更新他们的LIB

注意:我试过用标准的java运行这个,它们会导致同样的问题。这里还有我的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)

共有3个答案

白越
2023-03-14

我一直面临着同样的问题java.transaction.xa读取包从javaee和java.transaction.xa.我把这一行添加到我的modul-info.java

 opens javax.transaction.xa;

它工作得很好,但是提示显示包是javax。交易xa为空或不存在。但是,源代码编译正确。

韩玉石
2023-03-14

我也有同样的问题:

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

我可以通过检查我的项目传递依赖关系(gradle依赖关系或mvn依赖关系:树可能会有帮助)和排除代码simmiliar来摆脱拆分包编译问题:

configurations.all {
    exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.2_spec'
}

或者

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

我的问题是不需要重新包装罐子。#JDK8上没有出现此问题。排除依赖关系可能对每个项目都没有帮助。

斜光耀
2023-03-14

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

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

如果您不熟悉术语“拆分包”,它本质上是指来自两个不同模块的同一个包的两个成员。

例如:
com.foo.A(来自moduleA. jar)
com.foo.B(来自moduleB. jar)

我能对这个错误做些什么?

您有两个选择:

  1. (更难)拆分包依赖关系。然而,如果您不熟悉库的内部工作,这可能是困难或不可能的。
  2. (更容易)如上所述,将两个罐子合并成一个罐子(因此是一个单独的自动模块)。我同意这不是一个“好”的解决方案,但是首先使用分割包通常也不是一个好主意。

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

希望rx最终会更新他们的LIB,使其在将来某个时候不会有拆分包。在此之前,我的建议是将两个罐子一起打碎成一个罐子(选项2)。

 类似资料:
  • 随着Java9的临近,我认为将我的一些项目移植到Java9将是一个很好的学习练习。在我的一个项目中,我对rxjava和rxjavafx有依赖关系 我想创建这个项目作为一个命名模块。为此,我需要创建一个文件,我需要在这里指定和的要求。但是,这些库还没有任何模块信息。 为了解决这个问题,我读到我需要创建自动模块。据我所知,我需要重命名和jar,使其具有一个简单的名称,然后在参数中列出jar。然后在我的

  • 我想在java模块中使用CDI功能。我希望我的代码保持泛型,不依赖于特定的实现。 我使用Java11和Maven3.6.0。 为了简单起见,我的目标被简化为在java文件中导入包。当我在没有module(没有)的情况下这样做时,每件事都能正常工作。 我的理解是,CDI库应该采用一个受jar文件名称启发的自动模块名称。当我使用指令运行maven时,我在类路径中看到。我相信,如果我错了,请更正,这应该

  • 我的项目依赖于Netty Epoll Transport。以下是依赖关系: 无法派生模块描述符:netty-transport-native-epoll-4.1.17。final-snapshot-linux-x 86_64.jar netty.transport.native.epoll:无效的模块名:'native'不是Java标识符 有什么变通办法吗?(当然,除了“释放正确的netty神器”

  • 学习到这里,可以说 Python 基础学习基本接近尾声了。 目录

  • 主要内容:模块系统特征,创建模块Java 9是一种称为模块的新型编程组件。模块是一个自我描述的代码和数据集合,并有一个名称来标识它。 模块系统特征 使用模块组件,Java 9中增加了以下增强功能 - 引入了一个新的可选阶段,即链接时间。这个阶段介于编译时间和运行时间之间。 在此阶段,可以组合和优化一组模块,使用jlink工具制作自定义运行时映像。 javac,jlink和java有额外的选项来指定模块路径,它们进一步定位模块的定

  • 食氧;视窗7;JDK 9决赛从9日开始,21日结束;JUnit4.12和现有的应用程序。作为起点,可以编译、执行应用程序,并且所有JUnit测试都显示为绿色。现在我们使用eclipse生成文件模块信息。JAVA结果是: 但有一个错误:junit无法解析为模块。问题是:如何告诉文件junit没有定义任何模块,应该在兼容模式下运行?