0

We're migrating from Java 8 to Java 11.
We have a legacy project Y which depends on another legacy project X.
The project X has no sources, it's just a collection of about 300 jars.
The build is ant-based, no maven.

I cannot build the project Y now with JDK 11 (neither in Eclipse, nor externally)
because it says "The package org.w3c.dom is accessible from more than one module: , java.xml"

I get this error in Eclipse on a line which does import org.w3c.dom.Document;

When I do an external build (with ant, outside of Eclipse) I can build successfully (with basically the same build.xml as under JDK 8)?! How come only Eclipse is complaining?! Is it because of this javac bug which I reference below.

I was reading here (these are directly related to my issues):

https://stackoverflow.com/a/53824670/2300597
The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-December/014077.html

but I am still unable to fix these build issues.
I tried 7-8 different things but nothing helps.

I think the clash is between org.w3c.dom package from some of these 300 jars and the same package in the JDK module java.xml.

The weird thing is that org.w3c.dom.Document doesn't seem to be present in any of these 300 jars, it's just that other classes from the same package are present in jars.

I am deadlocked, I see no way to fix this.
I cannot lightly change project X because it's a shared library used by multiple legacy projects.
On the other hand, I cannot remove java.xml module from the build path of project Y.
So I don't know how to approach this.

Isn't there some way to just say: OK, use the classes from the JDK first, then use those from the JARs (even though they share the same package, they are not the same class).

What is the right way to fix these errors?

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • @meriton I said I read this but I still see no solution. That's why I am asking. – peter.petrov Jan 17 '22 at 15:58
  • Also, we don't need to know *how many* things you have tried, but *which* things you have tried. How else could we check whether you have already tried the solution we're about to describe? – meriton Jan 17 '22 at 15:59
  • @meriton OK, I tried things mostly in Eclipse, specifying different ways of making project Y depend on X (in the classpath, in the module path). Then changing various compiler options. Adding the 300 jars directly as JAR dependencies in project Y. Also tried turning project X into module, etc. etc. I cannot describe everything I've been doing 6-7 hours today. – peter.petrov Jan 17 '22 at 16:00
  • So I am asking in general, seems with this structure things are not going to work at all. Right? Seems we need a more general rework of all this. – peter.petrov Jan 17 '22 at 16:04
  • Well, that sounds like you haven't tried (3) solution from the answer I linked. So perhaps try that and report back? – meriton Jan 17 '22 at 16:05
  • @meriton I wanted to try it but do not understand it, maybe the Eclipse UI has changed, I have the latest version. I don't know what is meant by left and right there, and where to move what, a few screenshots might help. So I am not sure what it means, I reread it 3 times today. – peter.petrov Jan 17 '22 at 16:15
  • My question should not be closed. The accepted answer in that other question which I am referred to, I am not sure if that answer is still valid / up-to-date. I explained that I read it and tried to apply it but I don't see such tabs or dialogs in the latest version of Eclipse. – peter.petrov Jan 17 '22 at 20:02
  • @peter.petrov The JLS of a released Java version will not be changed and you are talking about Java 11. The answer is up-to-date and valid for Java 9 to 17 and probably also for upcoming versions. The UI is shown when the project's compiler compliance level is set to Java 9 or higher. You have to stick to Java 8 if you cannot avoid packages being accessible from more than one module. "latest version" is not a proper version number. The compiler settings for your project and what you don't see are missing. Everything has already been said in https://stackoverflow.com/a/53824670/6505250 – howlger Jan 17 '22 at 22:35
  • @howlger Yes, I was talking about the latest version of Eclipse and the UI elements it provides to fix the problem. I know that in Java rules haven't changed from 9 to 11. – peter.petrov Jan 18 '22 at 08:09
  • @peter.petrov What you say is not reproducible in the latest version of Eclipse. Please tell the exact version and the build id of your Eclipse; show what you have configured in _Project > Properties: Java Compiler_ and in _Project > Properties: Java Build Path_. Upgrading from Java 8 to 11 can be blocked by dependencies that are not ready for Java 11. The same can happen when upgrading to Java 16 or 17 when using reflection, as these versions are more restrictive than the previous versions. In the versions in between, stuff was removed that can be fixed by additional dependencies. – howlger Jan 18 '22 at 10:08

1 Answers1

2

Starting from version 9 Java supports JPMS (Java Platform Module System).

In the Java Platform Module System it is not allowed to use the same package in more than one module. So, the solution is to find modules (jars) that exports this package org.w3c.dom and to remove one of the modules or package in it.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • Thanks, can you elaborate on this part: "So, the solution is to find modules (jars) that exports this package org.w3c.dom and to remove one of the modules or package in it." I don't understand it. Note that I am still learning about JPMS, I am not very familiar with it. – peter.petrov Jan 17 '22 at 16:22
  • @peter.petrov You have a project, that has N dependencies. Your project and each dependency are a jar module, (if we are in jpms). So, the problem is that two modules in this set export this package, that is not allowed. So, the problem is to find modules (jars) that have this package. Be careful. Your project can use libA as a dependency, bu libA can use libB that has this package. So, in your IDE you should check not only your dependencies, but also the dependencies of the dependencies etc. Something like this. – Pavel_K Jan 17 '22 at 16:32
  • OK... let's say I have found these JARs which have `org.w3c.dom`. What do you mean then by "and to remove one of the modules or package in it." ? – peter.petrov Jan 17 '22 at 16:34
  • 3-4 jars (from these 300) have 2-3 classes from `org.w3c.dom` in them. E.g. jar1 has A,B,C, jar2 has C,D. Then the JDK module also has multiple classes from `org.w3c.dom`. But I cannot get rid of the jars 1,2 because someone might need org.w3c.dom.A even though class org.w3c.dom.A is not org.w3c.dom.Document e.g. So am I not stuck then?! – peter.petrov Jan 17 '22 at 16:40
  • OK, I will rethink what you're saying. These 300 jars are 3rd party jars, we don't have control over them. E.g. "xml-apis-ext.jar" or "jaxen-1.1.1.jar". These two e.g. contain `org.w3c.dom` and that clashes with the JDK module `java.xml` OK, if that's the main point then we have serious issues. I wonder why I can compile with ant. What I said originally that I cannot compile externally (outside of Eclipse) is not true. I can. But I cannot compile in Eclipse. – peter.petrov Jan 17 '22 at 17:03
  • @peter.petrov It's illegal according to the Java language specification. `javac` (which is used by default by Ant, Maven, Gradle, etc.) should give you the same error, but it does not. It's a confirmed bug of `javac` (see https://stackoverflow.com/a/53824670/6505250). Eclipse sticks to the JLS and not to some (buggy) implementations. – howlger Jan 17 '22 at 19:32
  • @howlger Thanks for the confirmation, that was my understanding too, that I am able to compile outside of Eclipse just because of this bug in javac. I still don't have a solution but at least I understand the problem much better now. – peter.petrov Jan 17 '22 at 20:06
  • 1
    There’s something apparently nobody has mentioned so far. Even if you manage to compile the code, *it will not run* unless you exclude `java.xml` from the environment, as otherwise, classes in the `org.w3c.dom` package will only be looked up in that module and nowhere else. But when you say you can’t exclude `java.xml` at build time (because it is used), you obviously can’t exclude it from the runtime either. That all assuming that these `org.w3c.dom.X` classes weren’t in the `java.xml` module anyway and hence, entirely redundant. – Holger Jan 18 '22 at 10:39
  • @Holger Thanks, I will rethink it all and see what's the best thing I can do here. Seems the legacy Java 8 approach which we have with this big monolith block of 300 jars in project X, and then multiple projects using X > that is exactly what we should not do in Java >= 9 as per JPMS. The funny thing is that javac doesn't enforce this... So I wonder what happens when we build the project with ant and we deploy it. Interesting which classes take priority then - those from the JDK modules or from the 3rd party jars? I wonder how Eclipse enforces it - after all Eclipse calls javac under the hood? – peter.petrov Jan 18 '22 at 13:05
  • @Holger I guess Eclipse has some sort of pre-check or something. I will have to read up a bit about all these topics. Thanks everyone for the help here. – peter.petrov Jan 18 '22 at 13:09
  • 1
    When I try to produce a similar scenario, `javac` *does* complain about the attempt to create, e.g. `org.w3c.dom.Foo`, and I have to pre-create it using Java 8 compliance level. Then, when this class does already exist, `javac` doesn’t complain about accessing `org.w3c.dom.Document` like Eclipse does but complains about accessing `org.w3c.dom.Foo`, just like the runtime would do. So it’s not as if `javac` was ignoring the issue. You have to deliberately adjust the options to get this code compiled. – Holger Jan 18 '22 at 15:00
  • @peter.petrov Was my answer correct? – Pavel_K Feb 05 '22 at 15:24
  • I think so. I ended up looking for classes/packages in jars, seeing what's causing these clashes, repackaging some jars into custom ones (by removing classes or packages from them), etc. etc. Dirty business basically... but at the end I got everything to compile successfully both in Eclipse and outside of it. Thanks for the help back then. – peter.petrov Feb 06 '22 at 22:51
  • @peter.petrov I understand you . I did a lot of things like this for JPMS support. – Pavel_K Feb 07 '22 at 06:13