How to resolve module reads package error in java9
Asked Answered
T

3

38

I am trying to understand new modularity in java 9 with spring-boot so I want to run some simple application for example: https://github.com/tmatyashovsky/java9-springboot

I am using maven 3.5.0 with 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"

Problem is I still got some exception. What does it mean and how should I fix it ?

[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
Theresatherese answered 22/6, 2017 at 11:13 Comment(4)
Which exact version of JDK9 are you using?Flam
latest early accessTheresatherese
@Theresatherese Most recent build: jdk-9+175, could you confirm ?Albertina
yes build: jdk-9+175Theresatherese
U
29

The problem is that your module path contains the same package (javax.annotation) in different modules (java.xml.ws.annotation and tomcat.embed.core), which the module system forbids in order to make configurations more reliable. This is called a split package. The module system tells you as much when listing all the modules that read (i.e. "see") that package twice. So what to do now?

The first order of business would be to check whether both packages contain the same classes. If yes, you're in luck. Now all you need to do is make sure the module system only sees one of those, for which there are two possibilities:

  • If from one of the modules, you only need the one package and nothing else, take it out of your configuration and use the other one instead. Maybe you can stop explicitly requiring java.xml.ws.annotation?
  • If you put tomcat.embed.core on the classpath, its version of the package will be completely ignored and the entire system, including the code on the class path will only see the package in java.xml.ws.annotation.

If both variants of the package contain types that (a) the other does not contain and (b) your application needs, you're in a tougher situation. First of all, that raises the suspicion that tomcat.embed.core did something fishy (although I'm not sure about that). The only thing I know could help could be the non-standard javac option --patch-module.

Unload answered 30/6, 2017 at 8:35 Comment(1)
Try doing that with a large exisiting multi module project and a lot of legacy dependencies. Good luck. I would only use java modules if i had to write a new program from scratch.Grassquit
A
9

In case of Spring Boot and embedded Tomcat, I faced a similar issue. There is a split package, that is included in javax.annotation:javax.annotation-api as well as in org.apache.tomcat:tomcat-annotations-api.

javax.annotation:javax.annotation-api is a transitive dependency of org.springframework.boot:spring-boot-starter-web.

In order to fix this for the particular case of Spring Boot and embedded Tomcat, adding the dependencies as shown below was the solution. I removed the dependency of javax.annotation-api explicitly. This works because tomcat-annotations-api provides all required packages and classes as well.

    <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>
Allcot answered 8/11, 2017 at 7:6 Comment(0)
G
2

I got following error:

[ERROR] module hibernate.core reads package org.hibernate.dialect from both ParentProject and hibernate.core

when trying to execute mvn clean install for my project ParentProject. The auto generated module-info.java for ParentProject contained the entries

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

The module-info.java of ChildProject contains

requires hibernate.core;

Removing the line exports hibernate.core; from the ParentProject resolved the issue for me.

=> Be careful with auto-generated module-info.java in Eclipse.

Gabby answered 11/11, 2017 at 15:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.