How to resolve module reads package error in java9

Solution 1:

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.

Solution 2:

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>

Solution 3:

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.