When referencing simple .jar files, Eclipse shows an error stating:
The package java.awt is accessible from more than one module:
, jav
Since I'll bet lots of people will be running into this problem with modular Java, I'll help and give the real answer. This error happens when you have a dependency in your project that contains code using packages that are also in the modules being referenced by your project. If your project has set the source compatibility to something like Java 12, it will start enforcing the rule, that has been there all along in Java. "Don't use packages that belong to the JDK in your own code." Unfortunately, lots of developers and vendors have done that over the years. Can't do that anymore. If you set your project to Java 12 source compatibility, Eclipse adds the JDK modules which include everything "java." and "javax." and even "jdk.", "org.w3c.". These packages may be in use by your dependencies or their transitive dependencies.
How to fix: You need to look at which package its complaining about and expand the "Projects and External Dependencies" node in the Package Explorer. Find out which dependency is using that package. Then you can simply exclude that dependency from your project. Or you could get the source of that dependency, if available, and rebuild the jar with changed packages. Otherwise you have to remove that dependency and find a replacement for that technology. Pain huh?
If its a transitive dependency you can often just exclude it. Here is an example of that for Gradle based projects.
configurations {
all*.exclude group: 'xml-apis'
}
I think my flavour of the problem might be useful.
I got this error for classes under javax.xml.stream
, by old Maven projects that depend on artifacts like xml-apis
, stax-api
, or geronimo-stax-api
.
Technically, the problem is what others have already said: those artifacts expose the javax.xml.*
package without any awareness of Java modules (they were born earlier), so the package goes automatically to the unnamed module, which conflicts with the same package being included in the Java's most recent versions, with its own module name.
That said, the practical solution is essentially to work with Maven exclusions to remove those dependencies from your project and let it use the JDK version instead. Use the equivalent if you're working with another build system. In theory, the JDK recent version might be non backward-compatible, in practice I doubt such JSR specifications changed much over the years and so far I haven't seen any issue with their replacement.
This is caused by
java.awt
that also exists in the system library but theIn the Java Platform Module System (JPMS) it is not allowed to use the same package in more than one module. If the Modulepath and the Classpath is used, everything on the Classpath is handled as the <unnamed>
module (in your case the package java.awt
exists in the system module java.desktop
and also via the JAR on the Classpath in the module <unnamed>
).
Since the JRE System Library cannot be moved from the Modulepath to the Classpath (see this answer by Stephan Herrmann for details), you only have the following options:
java
to java_util
and javax
to javax_util
) and recreate the JAR.class
files you have to decompile the .class
files firstYou can do what other people suggest which is to exclude xml-apis
which worked fine with me, but if your are using and an old jaxb-api
replace them with jakarta.xml.bind-api
:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
and of course upgrade your jaxb-impl
to match the same api:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
In my case, it was because I included a dependency (Apache Tika) in the POM.xml file.
I had to force the exclusion of the module that contained the classes with errors while imported at that dependency:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.24.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
It worked for me that way.
See also: The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml where I answered:
Disappointingly I don't see any compiler flags to show what jar the problem is with Even -Xlint:module doesn't seem to show up anything useful and eclipse doesn't shed any light on the issue
Instead to find where java.awt comes from I've been using this script:
mvn dependency:copy-dependencies -DincludeScope=test -DoutputDirectory=deps
for i in deps/*.jar; do if unzip -l $i| grep -q java.awt; then echo $i; fi ; done
Strictly you don't have to specify the scope test as that's the default but I've included it as you might want to use compile
instead