First of all I researched a lot about this issue already and it's is not a duplicate of the numerous and typical "The package * is accessible from more than one module: <unnamed>, java.xml" questions for which the simple answer is: "remove duplicate dependencies from your classpath".
This we already did and for the colleagues using IntelliJ IDE it also is working fine and not bringing up the issues Eclipse does.
I suspect it to be a side-effect of the special setup of the project which Eclipse is not handling well and therefore is leading to the issue. But one after the other:
In the end it's a "typical" "The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml" issue. But unlike having defined redundant, conflicting dependencies, it's more due to the special project setup and Eclipse not properly handling the project setup, since the conflicting dependencies both come from the same system library JRE.
From the server module:
We are working on the project for a long time now (big legacy project). During the work we've already upgraded from Java 1.6 over Java 1.8 to now Java 17. All the upgrades were fine so far except the last one. But only with the introduction of Java 17 also the new module server-util
was introduced, which seems to cause the issues (see below).
When using Java 1.8 in the Compiler-Options the project also is compiling fine, but as soon the Compiler-Options are increased to >Java 9 (e.g. 17) the compile issues occur.
The project is structured into 4 modules: client
, server
, share
and server-util
. Whereby client
and server
usually are independend modules and the share
is shared between the two. server-util
is a small utility module which provides additional utilities/ services for the server
module.
A graphical representation would look like this:
client server - server-util
\ /
share
All of the modules except the server-util
module are "simple" Java-Projects (so no Maven or Gradle is in place here (yet)). The build tool used for this modules is Ant. Only the server-util
module makes use of Gradle.
server
and server-util
modules. client - share
and server - share
don't show this kind of issues.server
module and server-util
use the same). But during the trace once it's opened from server
module and once from server-util
module (-> in the Package Explorer view). Therefore it seems Eclipse doesn't recognize it's the same JRE/ JDK being used within the projects (whereby it does recognize it between the client - share
and server - share
modules and therfore doesn't bring up the issues).server-util
project is a Gradle project Eclipse offers the Gradle -> Refresh Gradle Project
option in the context menu. Usually when I perform this operation this also leads to compile issues, since the usually configured JRE isn't recognized anymore or even actively reset. => When opening the Build Path of the module none of the available JREs is selected/ configured anymore. I always need to manually select "Workspace default JRE" (-> JDK 17) again.Since the setup is working for the colleagues using IntelliJ IDE and also at Build Time (-> Ant) and runtime everything is working fine I don't think it's a general or plain dependency issue.
My assumption is that Eclipse cannot handle the relationship between the server
and server-util
projects well. And the most obvious reason is that one is a plain, "simple" Java Project, whereby the other is a Gradle project. Therefore Eclipse doesn't seem to properly detect the usage of the same "system library -> JRE" and therefore falsely is claiming the error "The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml".
But it's not exactly clear if it's the combination of both or maybe even solely related to the Gradle project itself (whether it's our project's setup or some kind of issue with the Eclipse Gradle plugin or so).
I've tried different things like
So none of this helped.
I hope someone may have some experience with this and some other ideas to resolve the issues, even though the setup (plain Java-Project depending on Gradle project) may be quite special.
server-util
brings (in order of definition)Implementation scope
javaee-api-8.0.jar
slf4j-api-1.7.21.jar
antlr-2.7.7.jar
byte-buddy-1.11.20.jar
cache-api-1.1.0.jar
classmate-1.5.1.jar
dom4j-2.1.3.jar
ehcache-3.9.7.jar
hibernate-commons-annotations-5.1.2.Final.jar
hibernate-core-5.6.1.Final.jar
hibernate-jcache-5.6.1.Final.jar
jandex-2.2.3.Final.jar
javassist-3.24.0.GA.jar
jboss-logging-3.4.2.Final.jar
FastInfoset-1.2.15.jar
activation-1.1.jar
istack-commons-runtime-3.0.7.jar
javax.activation-api-1.2.0.jar
javax.mail-1.6.2.jar
javax.persistence-api-2.2.jar
jaxb-api-2.3.1.jar
jaxb-runtime-2.3.1.jar
jboss-transaction-api_1.2_spec-1.1.1.Final.jar
stax-ex-1.8.jar
txw2-2.3.1.jar
xml-apis-1.0.b2.jar
<-- may be the issue, but I'm still surprised why it didn't show up wile "tracing" it down & why it's compiling fine with IntelliJ ...)
So apparently during the creation of the minimal reproducible example (MRE) I was able to narrow down the issue and answer my own question - thanks to all the commentators for the support!
In the end it turned out that the problem was in module server
itself and that it was not related to the relationship of the modules server
and server-util
. Therefore the issue was also not caused by the Gradle nature of the server-util
module or Eclipse handling the setup.
The final root cause was the jaxp-api.jar
dependency of the server
module itself. It was duplicating the javax.xml
namespace/ package of the JRE, which is against the rules of the Java Platform Module System (JPMS) and therefore leading to the compile errors.
=> Contrary to what was assumed at the beginning, it was a typical dependency problem in the end.
Unfortunately it was masked by several impressions:
1 This you can do via "Ctrl + Click" -> Open Implementation
. But this time Eclipse opened 2x the JRE System Library (1x from server
module, 1x from server-util
module) instead of 1x the JRE System Library and 1x the conflicting jaxp-api.jar
as it used to do. Usually this always was a good and reliable way to identify duplicate/ conflicting libraries in the past.
In order to help others facing this or similar issues, let me explain which steps I performed to identify the root cause.
The crucial step is to prepare a minimal reproducible example (MRE) in order to view the individual components in isolation and narrow down the problem:
Create a small representative project server-reproduce
with just one (simple) class XMLUtils
, to reproduce the problem in the simplest form (-> check the bottom for the example code)
Create a small representative project server-util-java
as a simple Java project (-> not managed by Gradle) - containing no further dependencies than the workspace default JRE 17 System Library (-> same one as used by the server-reproduce
module)
Create a small representative project server-util-gradle
as a Gradle project (-> managed by Gradle) - containing no further dependencies than the workspace default JRE 17 System Library (-> same one as used by the server-reproduce
module)
Add the server-util-java
module as a project dependency to the server-reproduce
module
=> Expectation: No issues; Observation: No issues
Remove the server-util-java
module and add the server-util-gradle
module as a project dependency to the server-reproduce
module
=> Expectation: Issues will start to occur; Observation: No issues
This shows that the assumption that the problems were caused by Eclipse not being able to handle the combination of a simple Java project referencing a project managed by Gradle, and therefore not being able to properly resolve the JREs used, was not the root cause.
Further steps to locate the problem:
Remove the server-util-gradle
module as a project dependency from the server-reproduce
module
Add all the dependencies of the original server
module to the newly created server-reproduce
module
=> Expectation: No issues; Observation: Issues started to occur
This shows the issue must be solely within the setup/ dependencies of the server-reproduce
module and that no other project dependency is involved.
Unfortunately the earlier helpful way via "Ctrl + Click" -> Open Implementation
, which should show the conflicting library in the "Package-Explorer", didn't work here either. Again Eclipse opened 2x the JRE System Library (but this time the identical one) instead of 1x the JRE System Library and 1x the library causing the error.
Instead use the "Java-Search" from the Search window (-> Ctrl + H
) as follows:
This search now properly displays all dependencies introducing declarations for the conflicting class:
And reveals jaxp-api.jar
is causing the compile issues.
* Note: According to my expectation there is a minor bug in the "Java Search" if you're interested about this check out the section "Further reading" below.
To resolve the compile issues remove the jaxp-api.jar
and it's implementation(s) (like jaxp-ri.jar
) without replacement (jaxp-ri.jar
was not directly leading to compile issues, but also is obsolete with Java 9 and above). As per my research the former jaxp-api.jar
, which was distributed in a standalone bundle, has been integrated into the delivery of Java SE and therefore doesn't need a replacement.
Sources:
XMLUtils
example codeimport org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
public class XMLUtils {
private XMLUtils() {
// do not instantiate
}
/**
* Provides the value of the specified attribute - when present. Otherwise null
*/
public static String getAttributeValue(Node anElement, String attrName) {
NamedNodeMap nodeMap = anElement.getAttributes();
for (int i = 0; i < nodeMap.getLength(); i++) {
Node n = nodeMap.item(i);
if (attrName.equalsIgnoreCase(n.getNodeName())) {
return ((Attr) n).getValue();
}
}
return null;
}
}
Adding the following configuration line to a project's .settings/org.eclipse.jdt.core.prefs
as suggest by the link (https://stackoverflow.com/a/74890645/6505250) provided by howlger in the comments:
org.eclipse.jdt.core.compiler.ignoreUnnamedModuleForSplitPackage=enabled
also will resolve the compile issues.
Just make sure to use a recent version of Eclipse. The configuration shall be supported from Eclipse 2022-12. Therefore setting it on my original Eclipse 2021-06 had no effect, but was working fine with Eclipse 2023-09.
=> It must be highlighted that this is not recommended and rather a workaround! If possible the root cause should properly be fixed by resolving the conflicts in the project setup/ dependencies e.g. as described above.
Of course the real project's setup was not that simple and kept one more difficulty ready.
The module server
is not only dependent on the module server-util
, but server-util
also is physically contained in the project folder of the server
module as a subfolder.
It looks like that:
repository-root/
├─ server/
│ ├─ lib/
│ │ ├─ main/
│ │ │ ├─ libraries
│ ├─ server-util/
│ │ ├─ lib/
│ │ │ ├─ main/
│ │ │ │ ├─ libraries e.g. xml-apis-1.0.b2.jar
* server-util
being nested inside of server
This leads to the fact that if one sets up the project (server
) in a new workspace in Eclipse, it recognizes the libraries from server-util
and automatically adds them to the server
module. If you don't pay attention here it's very hard to recognize!
Of course this is Eclipse's known default behaviour and usually what one needs, but not for this project. Not paying much attention I overlooked it at first of course.
Therefore the resolution above was not enough and even though having removed jaxp-api.jar
from the build path the compile issues still occurred.
Luckily by using the "Java Search" (-> Ctrl + H
) as explained above I could identify the additional conflicting libraries quickly:
As can be seen above it turned out that also xml-apis-1.0.b2.jar
was leading to the compile issues. But this jar anyways was not expected to be on the build path from the beginning. Therefore, it was rather a coincidence that this step has become necessary and should actually not have been the case.
But this revealed a possible bug in the Eclipse "Java Search" (-> Ctrl + H
). As I reproduced the same scenario in my MRE I noticed the "Java Search" is not displaying all (conflicting) dependencies in my MRE projects even though it should. I suspect it's because the dependencies in my MRE were structured slightly differently and located outside of the project folder like the following:
eclipse-workspace/
├─ server-reproduce/
│ ├─ lib/
│ │ ├─ main/
│ │ │ ├─ libraries
├─ server-util-gradle/
│ ├─ lib/
│ │ ├─ main/
│ │ │ ├─ libraries e.g. xml-apis-1.0.b2.jar
* server-util-gradle
not being nested inside of server-reproduce
and residing on the same folder level
=> In this scenario the compile issues still remained (because the server-reproduce
referenced the xml-apis-1.0.b2.jar
), but the "Java Search" was not displaying it as a source of declaration for the conflicting classes, even though the checkbox "Application libraries" was ticked as displayed at the top. I want to highlight this, in case someone is following the steps described in this answer and may be wondering why not all conflict causing dependencies are displayed within the search.
=> To me it seems like a bug in the search in Eclipse, since in this scenario I definitely would consider xml-apis-1.0.b2.jar
to be an "Application library".
Why is xml-apis-1.0.b2.jar
leading to the compile issues when being referenced as a direct dependency in server
or server-reproduce
respectively, but when being pulled as a transitive dependency through server-util
(as a Gradle project) it's not?
=> This I still didn't figure out and it surprises me. Anyways it'll be not relevant for the project anymore since I'm planning to also remove xml-apis-1.0.b2.jar
entirely. But I'm still curious and would like to know. So if you have an idea feel free to let me know in the comments!