3

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:

Issue

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:

Compile errors

Project Background

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.

Tools

  • Eclipse 2021_06 (but the issues also occur with latest Eclipse 2023_09)
  • Java 17 (jdk-17.0.5+8)
  • Gradle (Wrapper) 7.4.2
  • Our project doesn't use module-info.java thus should reside in the default unnamed module

Project Setup

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.

Observations/ Issue

  1. When switching the Compiler-Options from 1.8 to 17 as explained above the issues start to occur. Interestingly the issues only arise between the server and server-util modules. client - share and server - share don't show this kind of issues.
  2. When tracing down the conflicting dependencies they both originate from the configured default JRE for the workspace which is a JDK 17 (both 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).
  3. Since 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.

Assumption

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

  • Using different Eclipse versions (from 2021_06 till finally latest 2023_09)
  • Changing Module Dependencies from Build Path settings
  • Using different Build Path settings like configuring the JRE in different ways
  • Moving the JRE from the "Modulepath" section to the "Classpath" section according to this question: In Eclipse, what is the difference between modulepath and classpath?. But as also mentioned in the question the JRE always remains in the "Modulpath" section

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.

EDIT:

The dependencies 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 ...)

Test scope

  • h2-1.4.200.jar
  • jmockit.jar
  • jmockit-deencapsulation.jar
  • junit-4.11.jar
  • hamcrest-all-1.3.jar
  • ojdbc8.jar
  • osdt_cert.jar
  • osdt_core.jar
9
  • Yes, the system library is always on the modulepath and everything on the classpath is considered in the <unnamed> module. Two modules must not contain the same package. Please read stackoverflow.com/a/55572922/6505250 and stackoverflow.com/a/53824670/6505250 But if you don't want to stick to the Java language specification, here you go (not recommended): stackoverflow.com/a/74890645/6505250 Commented Sep 22, 2023 at 15:38
  • Usually when the compiler says that you have a package in more than one place, it's right. What packages are in this server-util project and resulting jar, and are you planning to use or even care about Java modularization for what you're doing? Commented Sep 22, 2023 at 15:52
  • @nitind since it's a bigger legacy project for now we don't consider modularization (since many needed dependencies only exist in very old, not-modularized versions). Unfortunatley I'm not that familiar with the details of JPMS yet to properly asses the PROs and CONs. As of now I understood that's easier that way, therefore sticking with it for now (may change in future). Commented Sep 24, 2023 at 21:13
  • @nitind if that really is an issue I'm wondering why IntelliJ is building it fine for the colleagues and also there are no issues during the ANT build.. but let me try one thing tomorrow: I'll once disable the Gradle nature and try to add the dependencies manually. We'll see how Eclipse behaves then and if it really is a dependency or Eclipse [Gradle plugin] issue. I'll edit the post and add the dependencies of server-uti there Commented Sep 24, 2023 at 21:16
  • 1
    Can you please provide a minimal reproducible example (the minimal is important, e.g. as few dependencies as possible) so we can reproduce the issue? Also, check whether the issue would be resolved by a dependency update. Commented Sep 24, 2023 at 22:08

1 Answer 1

2

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!

Root cause

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. Eclipse misleading behaviour by opening the wrong library in the "Package-Explorer" view when looking for the sources of the conflicting libraries/ classes.1
  2. The project setup having been successfully imported by colleagues using IntelliJ IDEA
  3. The project being built properly by the build tools and operating fine in production

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.

How did I find out?

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:

  1. 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)

  2. 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)

  3. 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)

  4. Add the server-util-java module as a project dependency to the server-reproduce module

    => Expectation: No issues; Observation: No issues
    
  5. 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:

  1. Remove the server-util-gradle module as a project dependency from the server-reproduce module

  2. 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.

Finding the dependency causing the error

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:

Eclipse Java Search

This search now properly displays all dependencies introducing declarations for the conflicting class:

Java Search showing all conflicting declarations

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.

Resolution

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 code

import 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;
    }
}

For the record

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.


Further reading

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:

Conflicting dependencies on real project

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".

One final question remains though

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!

Sign up to request clarification or add additional context in comments.

1 Comment

Regarding your remaining question, you have to find out how xml-apis is referenced in Project > Properties: Java Build Path, which might be directly or indirectly (e.g. via dependency to another project or a transitive Gradle dependency).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.