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?
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.
Related
I have a big gradle project with a lot of gradle modules.
I want to add java11 support with back compatibility (with java 8).
1) Do I have to use java9 modules system, or such migration is possible without it ?
2) If yes, can I auto-generate module-info files automatically, my project is huge.
If not defined otherwise all you classes will be packed into a unnamed module.
But you should be able to run your app without code modifications.
I'm using OpenJDK 11, IntelijIDEA 2019.2 and javafx-sdk-11.0.2.
When I wrote JavaFX project, I tried to add external runnable jar from maven project, but IntelijIDEA didn't see classes for this jar.
What I've done:
I added as external library own jar.
In the project tree I found it:
But I couldn't create class objects and use methods that contains this jar:
Why it happens?
If it's modular project
The reason was the use of the file module-info.java. As we know, JavaFX 11 is not part of the JDK anymore. So, we need to add this special file at the root of our packages w/ lines like:
module modulename {
requires javafx.fxml;
requires javafx.controls;
opens package;
}
From this moment, most likely you won't find classes until you add separately your jar in this code like:
requires name_of_jar;
Only after adding this, you can use your classes/methods from external libs.
If it's non-modular project
As mentioned by mipa, you can follow these instructions as alternative way.
Related links:
https://www.baeldung.com/java-9-modularity
https://medium.com/criciumadev/its-time-migrating-to-java-11-5eb3868354f9
How to use 3rd party library in Java9 module?
https://www.oracle.com/corporate/features/understanding-java-9-modules.html
IntelliJ can't recognize JavaFX 11 with OpenJDK 11
In Eclipse, what is the difference between modulepath and classpath, and which one should I use to add a JAR file in the lib folder?
And why does the JRE System Library appear in modulepath?
The module system has mainly the following impact on the code:
A package can only be accessed from one module (Nested packages are treated as separate, so even though the package java.util is in the module java.base, the package java.util.logging can be in the module java.logging)
You can only access public fields and methods of code in exported packages of other modules. This is true even with reflection (i.e. java.lang.reflect.AccessibleObject.setAccessible(boolean) only works for code in the same module)
All code that is on the classpath lives together in the "unnamed" module.
All code on the modulepath lives in their own "named" modules.
You have to distinguish two cases:
If you don't add a module-info.java to your project, your project will be part of the unnamed module and can see all other code in the unnamed module, plus code in java.base and code in modules in java.se root module. Basically this means that w.r.t. code on the classpath, everything still works as in Java 8, so you should just put your dependencies on the classpath.
If you have a module-info.java in your project, your project will be in its own named module and can only see code in java.base and other named modules which are references using "requires"-clauses in the module-info.java. As named modules are only found via the module path, you should put your dependencies on the module path. This even works for jars created before Java 9, which will get a module name derived from the .jar file name (in which case they are called "automatic" module).
The JRE is always on the module-path, so that its internal code cannot be accessed even from code on the classpath.
There is one special case: If you have a module-info.java in your project and have test code in your project, you usually don't want to mention test dependencies like junit in the module-info.java. There are two solutions for this:
Create a dedicated test module. This has always been the convention for osgi-based projects. Disadvantage is that you can only use public API in your tests
The solution used by Maven: Put your test dependencies on the classpath. When compiling test code, Maven adds command line options that allow the code in the named module to read the unnamed module (which is not possible via the module-info.java).
In Eclipse Oxygen, the Maven solution was not possible, because it has no notion which code is test code, but this has been implemented in the upcoming Eclipse Photon (4.8) release, which will be out in June. You can already work with the (feature-complete) milestone builds from http://download.eclipse.org/eclipse/downloads/. In case you find any bugs, please report them at https://bugs.eclipse.org/bugs/.
I recently tried to upgrade from Scala 2.9 to 2.10 and ran into the following difficulties:
I have two scala eclipse-plugin projects. The first one has some unmanaged libraries on it's build path. This project compiles and runs fine.
The second project depends upon the first project and some Java project configured via eclipse-plugin dependencies.
Here I get four not very helpful compile errors. Three times the following
SBT builder crashed while compiling. The error message is 'bad symbolic reference. A signature in XSBInterRunner.class refers to term interprolog in value com.declarativa which is not available. It may be completely missing from the current classpath, or the version on the classpath might be incompatible with the version used when compiling XSBInterRunner.class.'. Check Error Log for details. de.wwu.sdpn.wala Unknown Scala Problem
Plus another dumping the class path which actually does not contain the corresponding library.
If I manually add the missing libraries to the second project the first project isn't found anymore. Even though it was on the dumped class path previously.
When compiling the projects from the command line via SBT using a more or less equivalent setup everything works fine.
I've also tried to reconfigure the dependencies not to use the eclipse-plugin mechanism for dependency management but directly added the other project to the build path but this also didn't help. Reimporting the projects to a clean workspace also didn't help.
The problem exists both with the 3.0.1 and the nightly version of the scala-ide plugin on Eclipse 4.2 and 4.3.
Any idea how to resolve this issue? Is there any way to find out why the libraries are missing from the class path?
From the description, it looks like the unmanaged library is not exported from the first project. Verify that in project properties > Java Build Path > Order and Export, the checkbox next to the library is selected. It is needed to make jars visible to other projects.
How to prevent compiling a package from amongst several packages in a netbeans based web app project?
Actually there are certain classes within that package that are uncompilable & they actually are responsible for not any of the other packages in project, making it to ../target/classes/ folder. While building the project I saw that the packages were compiled however there are no class files in the ../target/classes/ folder. However if I remove the uncompilable package, all the other packages successfully make it to ../target/classes/ folder.
This is covered in the NetBeans FAQ in the question: "Can I exclude some classes or packages from compilation"
Goto Project Properties
Select the "Sources" node in the left hand tree
Click on Include/Excludes in the lower left corner
Specify which files to exclude in the lower input field.
I dont about netbeans.. but in eclipse you an add an exclusion filter on the src directory. I am pretty sure you could do the same in netbeans too. And I think netbeans creates ant build file for the project, you could try modifying that file.