如何解决java9中的模块读取包错误

Posted

技术标签:

【中文标题】如何解决java9中的模块读取包错误【英文标题】:How to resolve module reads package error in java9 【发布时间】:2017-11-25 15:14:32 【问题描述】:

我正在尝试使用 spring-boot 了解 java 9 中的新模块化,因此我想运行一些简单的应用程序,例如:https://github.com/tmatyashovsky/java9-springboot

我正在使用带有 java 9 的 maven 3.5.0:

Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-03T21:39:06+02:00)
Maven home: ~/soft/apache-maven-3.5.0
Java version: 9-ea, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-9-oracle
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-79-generic", arch: "amd64", family: "unix"

问题是我仍然有一些例外。这是什么意思,我应该如何解决?

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project api: Compilation failure: Compilation failure: 
[ERROR] module  reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.core reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.jcl reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.aop reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.expression reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.starter.web reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.starter reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.autoconfigure reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.starter.logging reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module logback.classic reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module logback.core reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module slf4j.api reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jul.to.slf4j reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module log4j.over.slf4j reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.starter.json reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.databind reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.annotations reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.core reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.datatype.jdk8 reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.datatype.jsr310 reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jackson.module.parameter.names reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.boot.starter.tomcat reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module tomcat.embed.core reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module tomcat.embed.el reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module tomcat.embed.websocket reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module hibernate.validator reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module validation.api reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module jboss.logging reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module classmate reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.web reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.webmvc reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.context reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module spring.beans reads package javax.annotation from both tomcat.embed.core and java.xml.ws.annotation
[ERROR] module com.lohika.morning.java9modules.service reads package javax.annotation from both java.xml.ws.annotation and tomcat.embed.core

【问题讨论】:

您使用的是哪个版本的 JDK9? 最新抢先体验 @hudi 最新版本:jdk-9+175,你能确认一下吗? 是构建:jdk-9+175 【参考方案1】:

问题是你的模块路径在不同的模块(java.xml.ws.annotationtomcat.embed.core中包含相同的包(javax.annotation) ),为了使配置更可靠,模块系统禁止。这称为split package。当列出两次读取(即“看到”)该软件包的所有模块时,模块系统会告诉您同样多的信息。那么现在该怎么办呢?

首要任务是检查两个包是否包含相同的类。如果是的话,你很幸运。现在您需要做的就是确保模块系统只看到其中之一,有两种可能性:

如果从其中一个模块中,您只需要一个包而无需其他任何东西,请将其从您的配置中取出并改用另一个。也许您可以停止明确要求​​ java.xml.ws.annotation? 如果你把 tomcat.embed.core 放在类路径上,它的包版本将被完全忽略,整个系统,包括类路径上的代码只会在 java.xml.ws.annotation 中看到包。

如果包的两个变体都包含 (a) 另一个不包含的类型以及 (b) 您的应用程序需要的类型,那么您的处境将更加艰难。首先,这让人怀疑 tomcat.embed.core 做了一些可疑的事情(尽管我不确定)。我知道的唯一可以帮助的可能是non-standard javac option --patch-module

【讨论】:

尝试对现有的大型多模块项目和大量遗留依赖项进行此操作。祝你好运。如果我必须从头开始编写一个新程序,我只会使用 java 模块。【参考方案2】:

我收到以下错误:

[ERROR] 模块 hibernate.core 从 ParentProject 和 hibernate.core 读取包 org.hibernate.dialect

尝试为我的项目ParentProject 执行 mvn clean install 时。 为ParentProject 自动生成的module-info.java 包含条目

...
exports hibernate.core;
...
requires ChildProject;
...

ChildProjectmodule-info.java 包含

requires hibernate.core;

ParentProject 中删除exports hibernate.core; 行为我解决了这个问题。

=> 小心在 Eclipse 中自动生成的 module-info.java。

【讨论】:

【参考方案3】:

在 Spring Boot 和嵌入式 Tomcat 的情况下,我遇到了类似的问题。有一个拆分包,包含在javax.annotation:javax.annotation-apiorg.apache.tomcat:tomcat-annotations-api 中。

javax.annotation:javax.annotation-apiorg.springframework.boot:spring-boot-starter-web 的传递依赖。

为了解决 Spring Boot 和嵌入式 Tomcat 的特殊情况,添加如下所示的依赖项是解决方案。我明确删除了javax.annotation-api 的依赖关系。这是因为tomcat-annotations-api 也提供了所有必需的包和类。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <!-- served by tomcat-annotations-api instead -->
                <groupId>javax.annotation</groupId>
                <artifactId>javax.annotation-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-annotations-api</artifactId>
    </dependency>

【讨论】:

以上是关于如何解决java9中的模块读取包错误的主要内容,如果未能解决你的问题,请参考以下文章

java9模块不可见问题

java9 新特征

java 9模块从A和B读取包X.

如何使用 Tailwind CSS 读取和解决 Rails 中的 Webpack 错误?

如何解决 Pyinstaller 模块未找到错误

Java9模块化系统