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

2022-09-01 06:59:24

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

我正在使用maven 3.5.0和java 9:

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

答案 1

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

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

  • 如果从其中一个模块中,您只需要一个包而不需要其他任何包,请将其从配置中取出,改用另一个包。也许你可以停止显式要求java.xml.ws.annotation
  • 如果将 tomcat.embed.core 放在类路径上,则其包版本将被完全忽略,整个系统(包括类路径上的代码)将只能看到 java.ws.annotation 中的包.xml。

如果包的两个变体都包含 (a) 另一个变体不包含的类型,并且 (b) 您的应用程序需要这些类型,则您处于更艰难的境地。首先,这引起了人们的怀疑,即tomcat.embed.core做了一些可疑的事情(尽管我不确定这一点)。我唯一知道可以提供帮助的可能是非标准的javac选项--patch-module


答案 2

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

javax.annotation:javax.annotation-api是 的传递依赖项。org.springframework.boot:spring-boot-starter-web

为了在Spring Boot和嵌入式Tomcat的特定情况下解决此问题,解决方案如下图所示添加依赖项。我显式删除了 的依赖关系。这之所以有效,是因为还提供了所有必需的包和类。javax.annotation-apitomcat-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>

推荐