Eclipse is confused by imports ("accessible from more than one module")
Asked Answered
B

18

76

When referencing simple .jar files, Eclipse shows an error stating:

The package java.awt is accessible from more than one module: <unnamed>, java.desktop

This happens for instance when javax.awt or javax.swing is included in the .jar files.

The simplest example would be the following:

package test;

import javax.swing.JDialog;

public class Test {
    public static void main(String[] args) {
        new JDialog();
    }
}

Adding a .jar file to the classpath with only the folder structure javax/swing (no files needed) will cause the error to appear. I'm using JDK 10/12 (neither works). Setting the compiler compliance to 1.8 makes the whole thing work again. On another machine with Eclipse 2018-09 this works with compiler compliance set to 10.

I'm on Eclipse 2019-03, on a (for testing purposes) freshly installed Eclipse 2018-09 it works fine. Why?

Edit June/2020 (Solution)

As the answers correctly stated, this is a restriction built into Java ages ago and only recently was forced upon us. I came into contact with it while migrating a big project with dozens of dependencies to Maven. There were libraries from around the year 2000! There were 'meta libraries' which consisted of several libraries packaged together. So there was no other way than to identify what was still needed (into the trash with the rest!), update libraries which violate the rules or find replacements for them. This took me many, many hours.

In the end it worked out and we've got a nice Maven project to work with.

Brockbrocken answered 8/4, 2019 at 10:13 Comment(7)
That's a restriction by the Java Platform Module System (JPMS), not by Eclipse (so don't shut the messenger). If you delete the file module-info.java in your default package (which disables JPMS) it should work with Java 9 or higher.Ethnography
This happens when not creating the module-info.java.Brockbrocken
I uploaded a video showing my problem on a freshly installed 2019-03: youtu.be/6fQ8ZPprVyoBrockbrocken
I see. Solves moving the JRE System Library from the Modulepath to the Classpath your issue?Ethnography
As you can see at roughly 34 seconds into the video, it's inside the classpath already (I never had it anywhere else). Funnily, after moving it to the module path, the errors disappear. This does not work on the real project, however, where I originally found the error.Brockbrocken
Everything must be on the classpath, the JAR and the JRE System Library (the video shows only the JAR being on the classpath).Ethnography
The JPMS rule is that it's illegal to HAVE the same package in two or more places. Say you have classpath "your.jar:my.jar", and both jars have "com.that.package" -- which version of that package in whose jar will be used? Just because your jar appears before my jar in the classpath is not a definitive and predictable way to build and run stuff. Making it illegal forces programmers to remove this ambiguity. The problem with Eclipse is that the error couldn't go one step further to identify which of the two module/jars HAVE the same package -- which can save everyone's headache and time.Culver
E
62

This is caused by

  • a JAR on the Classpath that contains the package java.awt that also exists in the system library but the
  • JRE System Library is on the Modulepath

In the Java Platform Module System (JPMS) it is not allowed that the same package is made visible by 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 is exported by the system module java.desktop and also exposed by the <unnamed> module, as it is contained in a JAR on the Classpath.

Since the JRE System Library cannot be moved from the Modulepath to the Classpath (see this answer by Stephan Herrmann for details), you have the following options:

  • Set the compiler compliance to 1.8 (as you already mentioned)
  • Rebuilt the JAR to avoid Java system library package names inside the JAR (if reflection is used, additional code changes may be necessary):
  • If you have the source code, change the package names (e.g. change the package and subpackae java to java_util and javax to javax_util) and recreate the JAR
  • If you have only the .class files you have to decompile the .class files first
Ethnography answered 8/4, 2019 at 11:55 Comment(16)
It's not possible to add the JRE to the Classpath.Brockbrocken
@KrannSock I have extended my answer by how this is possible.Ethnography
@howlher No matter what you do - it gets added back to the Modulepath.Brockbrocken
@KrannSock Yes, you're right. As far as I know, this was possible in previous versions. Is repacking the JAR an option for you?Ethnography
I could repack them manually, there are like 5 of them. Any instructions on what do do with those? Or do you mean just changing the folder/package names inside the jar? They are all very old libraries from ~2004. Is it not possible to use (partial) package paths of the JRE System Library any more in a jar file? To be honest, I also don't see a reason for this to be necessary - but apparently those libraries do :-)Brockbrocken
@KrannSock Yes, change the folder/package names inside the JAR. javax.swing.foo would work, but I would not recommend it. You should not use package names that are used by others, especially not of the standard library. Previously this was only a recommendation. Since Java 9 (with JPMS) this can cause problems like yours.Ethnography
Even javax.swing.foo doesn't work (this is the case in one of those libraries where it's javax.swing.xyz with only .gifs in it - you better don't ask...). If you add the explanation to your answer I'll accept it. Thank you very much!Brockbrocken
@KrannSock I've edited my answer. Tell me if anything is missing.Ethnography
I have this problem BUT both the JRE System Library and the referenced library JAR files are on the Classpath, nothing is on the modulepath. FML.Radiometer
@NeilBartlett In Java 9+ the JRE System Library is per se on the Modulepath, not on the Classpath (I have corrected my answer accordingly): see this answer by Stephan Herrmann for details. What compiler compliance level have you set in your project? Which Java version and which Eclipse version do you use?Ethnography
@Ethnography Thanks for the link. Unfortunately adding module-info.java is not a practical solution because as soon as you do this, you require all dependencies of the project to be modules, or at least to have automatic module names. Many of my dependencies do not have the Automatic-Module-Name header so I have to use the filename. So com.google.guava_21.0.0.jar becomes requires com.google.guava.21.0.0 but this is a syntax error in the module-info! Catch 22...Radiometer
@Ethnography You said that the JRE System Library is "per se on the modulepath, not the on the classpath". Maybe there is a bug in Eclipse 2019-06 because the JRE System Library is clearly shown under classpath in the Java Build Path properties page, NOT under modulepath.Radiometer
@NeilBartlett In Eclipse 2019-09 I was not able to reproduce this. The JRE System Library is shown on the modulepath, cannot be moved to the classpath (like a JAR) and even after directly editing the .classpath file (removing the line <attribute name="module" value="true"/>) the JRE System Library is still shown on the modulepath. Please upgrade and try again.Ethnography
Hi, is there any command (maybe for maven) which lists me the dependencies which add these packages? I would like to exclude them manually since they seem to be broken for Java11.Nibbs
@Ethnography It will explain the rule better if you change the word "use" in your first sentence to "have": "In ... (JPMS) it is not allowed to HAVE the same package in more than one module." This makes perfect sense for modules and/or classpath. Say you have classpath "your.jar:my.jar", and both jars have "com.that.package" -- which version of that package in whose jar will be used? Just because your jar appears before my jar in the classpath is not a definitive and predictable way to build and run stuff. Making it illegal forces programmers to remove this ambiguity.Culver
@MichaelChen Thanks for the hint. I changed the wording to "made visible" ("have" is not enough, as the package needs to be exported so that it is accessible).Ethnography
F
38

I found a simple solution to troubleshoot this in Eclipse.

  1. Hit Ctrl + Shift + T in Eclipse to open the Open Type prompt.
  2. Type the name of the package that is causing the issue. For me, it was org.w3c.dom
  3. The search results will show all the locations from where this package is being loaded.
  4. Remove every JAR from the classpath that comes in the result other than the JDK 11 library.

My project being a legacy one, I had to remove a lot of JARs from the build path. Also, my project does not use Maven. So removing the JARs was a fairly straightforward step. The steps might vary for other build tools like ANT, Maven, Gradle, etc. I have just explained the troubleshooting steps above.

Franckot answered 30/3, 2022 at 7:36 Comment(4)
Ctrl + Shift + T - works great. I was able to see that a jar was located in both the JRE and in an m2 repository.Duna
Ctrl + Shift + T was a lifesaver! Everyone explains the problems, but nobody explains how to find the dependency in question.Livelong
This is much more helpful than the higher rated answers.Katelyn
Good answer. I had error on this import javax.xml.XMLConstants; and i was able to find that was use in a stax-api which I could excludeOust
G
35

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.

GradleConfig.xml:

configurations {
   all*.exclude group: 'xml-apis'
}
Groggery answered 11/12, 2019 at 21:54 Comment(5)
"Don't use packages that belong to the JDK in your own code." what does this statement mean? Are you saying I cannot have a package javax.matt, because javax belongs to the jdk?Icebreaker
That's right. For example Java "owns" the package "java" so "java.anything" would not be allowed. Same for "sun.anything", "javax.anything".Groggery
import javax.xml.parsers.ParserConfigurationException; This statement is causing me the error. When I expand the "Projects and External Dependencies" I found xmlParserAPIs-2.6.2.jar is using the package javax.xml.parsers. So in build.gradle I did configurations { all*.exclude group: 'xmlParserAPIs' } but all in vainAmsterdam
Can you....explain what the answer means? Like...what is the problem? "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." What is a dependancy? How do i know if i have a dependancy? How do i know if a dependancy is in my project? How do i know if the dependancy in my project contains code? What is a module in my project? What does it mean for a module to reference a module? It sounds like if Java internally does import java.io; then my code is not allowed to call import java.io;.Berke
Of all the answers, excluding xml-apis worked for me!Candelariacandelario
A
28

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.

Away answered 17/8, 2020 at 18:5 Comment(2)
In my case the problem came with the dependencies for org.apache.xmlgraphics batik-transcoder 1.13 and batik-codec 1.13. The exclusion as you describe here (adapted to the batik dependencies) worked for me.Majors
I had the same problem with Batik too. Thank youEase
P
13

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 invented later), so the package is automatically assigned to the unnamed module, which conflicts with the same package being included in the JDK's most recent versions, where the package has its own module name, and therefore the same package results in two different modules, which is forbidden.

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 (or, of course, remove them as direct dependencies, if that's your case). Use the equivalent if you're working with another build system.

In theory, the more recent flavours of these packages offered by the JDK 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.

Pail answered 28/8, 2020 at 11:28 Comment(1)
Very helpful on list of conflicting deps. Thank you.Interdepartmental
A
12

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

Atabrine answered 9/7, 2020 at 6:50 Comment(2)
Will jdeps help here in seeing which two packages are conflicting ?Greenhead
This is the answer that helped the most. This allowed me to identify the 2 jars that were causing the issue. Thanks for sharing!Brutal
C
7

I've found some interesting behaviour with Java 11 and the xmlbeans library. The xmlbeans library is a transitive dependency of Apache POI, a very popular library for working with Microsoft Office documents, it is used to handle the internal XML structures of the newer Office formats. I've tested it with Apache POI 3.9 and it works perfectly fine, despite the error shown by Eclipse. So, I guess in Java 11 this rule it's not fully enforced.

Crescentic answered 10/3, 2021 at 12:32 Comment(1)
Came here with exactly the same problem when updating to the 5.0.0 of Apache POI, adding <exclusions><exclusion><groupId>xml-apis</groupId><artifactId>xml-</artifactId></exclusion></exclusions> to the poi-ooxml dependency did the trickLoader
H
3

For Apache POI version 5.0.0 using Maven, in the pom.xml:

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.0.0</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>5.0.0</version>
  <exclusions>
    <exclusion>
      <groupId>xml-apis</groupId>
      <artifactId>xml-apis</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Fixed: "The package javax.xml.parsers is accessible from more than one module"

Hull answered 17/11, 2021 at 9:20 Comment(0)
W
3

Configuration property was added to Eclipse. Full discussion here.

File: <workspace>\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.core.prefs
Property:
org.eclipse.jdt.core.compiler.ignoreUnnamedModuleForSplitPackage=enabled

Womanize answered 23/2, 2023 at 18:16 Comment(0)
P
2

Wow, this was a tough one!

Some helpful tips (a summary of my journey through this maze):

This started when I migrated from Java 1.8 to 11.0.11

Right out of the gate this caused problems. I needed to change the syntax for how to specify the Java version for the maven build plug in as shown below:

Before

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

After

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <release>11</release>
            </configuration>
        </plugin>       

After that, everything compiled at a command prompt. However, when opening the project in Eclipse, I got a bunch of errors as shown in the next section.

Getting "<class> cannot be resolved to a type" errors

When I got errors in Eclipse and not at the command line I immediately started looking at configuration settings in Eclipse to no avail. After some googling I came to this post. The post at https://www.eclipse.org/forums/index.php/t/1110036/ was also very helpful.

Finding what resources were the problem

The answer to this post by @Anu suggesting using <shift><ctrl>T to bring up the type search window was very helpful using this I was able to see what resources were causing the problem (i.e. any resource that is also included in the JDK, in my case it was the ErrorHandler in the xml-apis jar). Type the name of one of the resources giving a "cannot be resolved to type" to see the name of the jar file, in my case the jar is xml-apis-1.4.01.jar.

All of this is shown in the screen shot below (click on the image to get a cleaner view).

enter image description here

Finding the Dependency that contains the offending jar

We can now use the information from https://www.eclipse.org/forums/index.php/t/1110036/ to find the dependency in our pom.xml file that contains the offending resource.

Open the pom.xml file in Eclipse and select the "Dependency Hierarchy". In the filter type the name of the jar file we found in the previous step (in my case it was xml-apis).

This will pull up the dependencies creating the problem. A screen shot of the Dependencies Hierarchy filtered for "xml-apis". From this we can see the offending dependencies in our pom.xml file are xercesImpl and xlsx-streamer.

enter image description here

Solving the problem

We can now add exclusions to these dependencies that will resolve the problem as shown below.

    <dependency>
        <groupId>com.monitorjbl</groupId>
        <artifactId>xlsx-streamer</artifactId>
        <version>2.1.0</version>
        <exclusions>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>



    <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.12.0</version>
        <exclusions>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

And this fixes the current problem.

enter image description here

Pliam answered 23/9, 2022 at 18:25 Comment(0)
F
1

You 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>
Fabrizio answered 2/10, 2020 at 18:28 Comment(0)
O
1

I met a similar issue with the eclipse IDE while upgrading JDK from 1.8 to 11, "The package org.w3c.dom is accessible from more than one module: , java.xml". upgrading eclipse from 2019 to 2021 and setting system JDK home to 11 does not solve it. I don't think it's caused by "org.w3c.dom" existing in different jars of the classpath,dut to "Order and Export" should ordered the search sequence.

After several hours of searching and investigating, this issue is fixed by setting the Java Compiler - Compiler compliance level to 1.8(default is 11).

Oleaceous answered 29/11, 2021 at 7:13 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Syntactics
T
1

Steps below helped me:

Right click Eclipse project > Properties > Java Build Path In Libraries tab, remove all the external jar files under Modulepath and add them under Classpath (you can just select all the jars and drag them under Classpath) Click Apply and Close

Tomkin answered 25/7, 2022 at 15:1 Comment(0)
M
0

I had this problem with the Stanford Core NLP package. As mentioned above adding an exclusion in the pom.xml solved the problem:

    <dependency>
        <groupId>edu.stanford.nlp</groupId>
        <artifactId>stanford-corenlp</artifactId>
        <version>4.5.2</version>
        <exclusions>
           <exclusion>
             <groupId>xml-apis</groupId>
             <artifactId>xml-apis</artifactId>
           </exclusion>
        </exclusions>
     </dependency>
Morra answered 12/2, 2023 at 12:20 Comment(0)
B
0

For me adding JRE into classpath solved the problem.

project -> build path -> configure build path -> then adding JRE into class path

Barnaby answered 19/6, 2023 at 12:0 Comment(0)
A
0

I know that the question is for Maven. However, I'm going to post the solution for my case in gradle. In the configuration section of build.gradle file(version 7.4), just we need to add:

configurations.all {
     exclude group: 'xml-apis', module: 'xml-apis'
}

You must add the line for the projects that have the error.

Aarau answered 13/9, 2023 at 16:47 Comment(0)
G
0

Eclipse Error: The package javax.xml.namespace is accessible from more than one module: unnamed,java.xml

After a huge search, I've applied below workaround on my Eclipse(2023) & JDK-20 project and it worked very smoothly. Here is my experience:

  • My latest Eclipse version: eclipse-jee-2023-09-R-win32-x86_64 with inbuilt "JustJ JRE for IDE Packages" plugin was installed.
  • JDK Installed: java version "20.0.2", Java(TM) SE Runtime Environment (build 20.0.2+9-78)

Root-cause: Same 'javax.xml.namespace' package is used on both JARs, which are available on both 'Maven Dependencies'(i.e. axis.jaxrpc.jar) and 'JRE System Library'(i.e. java.xml.jar)

Debug/Troubleshoot: We must have to find all the referenced jars used in your eclipse project which having same package/class 'javax.xml.namespace'.

From your Eclipse IDE: 1. Press Ctrl+Shift+T to open the Type 2. Type the package.class name: javax.xml.namespace and identify the jars enter image description here

3. Search and identify the package/class from the jars available under Maven Dependencies & JRE System Library tree of your Eclipse IDE enter image description here

How to fix: Here is the work-around can be applied on your Eclipse Java project 1. Right-click on your eclipse java project, Click Properties->Java Build Path->Order and Export tab, Select Maven Dependencies, Click Down or Bottom: enter image description here

2. Sending the Maven Dependencies to the bottom, means below the JRE System Library then click Apply like below: enter image description here

Gilbreath answered 20/9, 2023 at 6:20 Comment(0)
B
-1

First of all, make sure your pom is actually correct by running mvn install

if that works, and eclipse still complains look at build path and find the library it is holding onto that is not in your pom.

Sometimes I just

rm .classpath
rm -rf .settings
rm -rf project
mvn eclipse:clean eclipse:eclipse
Bumble answered 1/6, 2022 at 4:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.