I'm trying to use Java Modules in my Spring Boot project and I'm getting the following exception:
java.lang.module.ResolutionException: Modules jsr305 and java.annotation export package javax.annotation to module org.jvnet.staxex
How can I solve this problem?
Try using JDK8 to run this code.
It seems to be a compatability issue
Edit:
The root cause is that this package has been removed. (https://jcp.org/en/jsr/detail?id=305) from the standard JVM installation after java 8.
Some of the dependencies in your code depends on it, therefore, there is a launch probelem. It comes from this dependency org.jvnet.staxex. Its used for XML parsing. Swapping it out for another package, which does not have this dependency is likely to be time consuming if you have a large XML-related code base.
What might work is trying to manually add the dependency which provides these classes. Try adding this to your dependencies
Also, this blog post might help
Related
I have a JavaFX application that works as expected. I need to use Apache POI to read and write excel files. The following are the steps I have taken:
Added the required dependency
implementation 'org.apache.poi:poi-ooxml:5.2.3'
Added the module to module-info.java
requires org.apache.poi.ooxml;
Tried to use the library within a function:
#FXML
private void downloadTemplate() {
XSSFWorkbook workbook = new XSSFWorkbook();
}
All this is fine with no issues. However when I try to run the application, I get the following two errors (interchanging)
> Task :Start.main() FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Module SparseBitSet not found, required by org.apache.poi.ooxml
and
> Task :Start.main() FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Module commons.math3 not found, required by org.apache.poi.ooxml
I can however, clearly see both libraries under 'external libraries'
I am using IntelliJ Community Edition 2022.1.2 and running the project using Java 17.0.1. Any help would be highly appreciated.
SparseBitSet is an automatic module, it has no module-info of its own (probably commons-math3 is as well), and is without an Automatic-Module-Name entry in its manifest.
Gradle puts libraries without a module-info.class or an Automatic-Module-Name in their manifest on the class path, not the module path, so they won't be treated as modules, and the module finder won't find them.
You can:
hack the gradle build to allow the modules to be found. (I don't use Gradle so I have no specific advice on how to do that other than referring to the documentation).
Hack the library jar which you want to be treated as a module to include a module-info.class or an Automatic-Module-Name in its manifest.
Or, switch to maven, which automatically places automatic modules on the module path.
The easiest way to do this, IMO, is to create a new JavaFX project in Idea, then add the required dependencies as maven dependencies and add your code.
Or, as swpalmer suggests in the comments, request that library maintainers update their codebase to make their libraries modular.
And, when you run your app, make sure all jars are on the module path, not the class path.
Or, make your app non-modular by removing the module-info.java from it, then manually place the JavaFX modules on the module-path and add them with the --add-modules switch.
FAQ
Are you SURE that automatic modules are put on the class path by Gradle?
From the Gradle documentation section Building Modules for the Java Module System:
To tell the Java compiler that a Jar is a module, as opposed to a
traditional Java library, Gradle needs to place it on the so called
module path. It is an alternative to the classpath, which is the
traditional way to tell the compiler about compiled dependencies.
Gradle will automatically put a Jar of your dependencies on the module
path, instead of the classpath, if these three things are true:
java.modularity.inferModulePath is not turned off
We are actually building a module (as opposed to a traditional
library) which we expressed by adding the module-info.java file.
(Another option is to add the Automatic-Module-Name Jar manifest
attribute as described further down.)
The Jar our module depends on is itself a module, which Gradles
decides based on the presence of a module-info.class — the compiled
version of the module descriptor — in the Jar. (Or, alternatively, the
presence of an Automatic-Module-Name attribute the Jar manifest)
It is the third point that is key. Java can treat a library with no module-info.class and no Automatic-Module-Name in the Jar manifest as an automatic module if it is on the module path. However, Gradle will by default, only place libraries which fulfill one of those two conditions on the module path.
Using jewelsea's answer above, I have been able to solve the problem. I am posting the answer here to help anyone else who encounters the problem in future.
So, the overall problem is, as said in the answer above, both SparseBitSet and commons-math3 are automatic modules with no module-info of their own. The solution that worked for me was to convert them into the modules expected by the project. Here are the steps I took:
Use a gradle plugin 'extra-java-module-info'. The github page didn't show how to import it to a normal gradle file so here it is:
plugins {
id 'org.gradlex.extra-java-module-info' version '1.0'
}
Note the names that your application expects for the modules. In my case, from the error messages thrown, they were 'SparseBitSet' and 'commons-math3'
Locate the said libraries on the sidebar under 'external libraries' and note the 'jar' file names. In my case, they were 'commons-math3-3.6.1.jar' and 'SparseBitSet-1.2.jar'.
Add a section 'extraJavaModuleInfo' to your gradle files and use the parameters as follows: module('jar file name', 'name expected by your project', 'jar version'), as shown in the blue rectangle in the image above.
extraJavaModuleInfo {
module('commons-math3-3.6.1.jar', 'commons.math3', '3.6.1')
module('SparseBitSet-1.2.jar', 'SparseBitSet', '1.2')
}
That's it. Try to sync and run your project. Thanks jewelsea.
I updated an Eclipse RCP Project from Eclipse 2019-12 to 2020-03. After the update I get build errors on export, like the following:
"The package javax.xml.parsers is accessible from more than one module: , java.xml".
I am using Java 11, no module-info.java file, the Eclipse 3 Compatibility Layer and the eclipse product export wizard in my project.
The error message basically is clear to me. It detects some class twice on classpath, which is not allowed. Once the class is provided by JDK module "java.xml". The second copy comes from javax.xml osgi bundle.
My problem is that both of the packages can not be removed. The JDK module has a lot of dependent JDK modules that are actively used in code and I don't think that they can be supplemented by some libraries. The OSGI bundle is used by a lot of very basic eclipse bundles. So it can also not be removed.
So I have two questions:
Why does Eclipse RCP break projects with its new version? Was that considered a bug before? (I did not find a ticket)
How can I get my project to run again without really big changes?
Edit 1: Added reproducible example:
https://workupload.com/file/wKUZTXJXsR9
Edit 2: See also Eclipse Bug Ticket:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=562761
I created a minimum example. One can see the problem by exporting the product via wizard. I used DocumentBuilderFactory from javax.xml in Application.java to trigger the problem.
I found out a few things:
A plugin dependency to org.eclipse.help.ui is needed to trigger the problem. Although also other plugins have dependencies to javax.xml plugin.
Eclipse tells you the problem in Editor if I you add a direct dependency to javax.xml plugin. But we have only a transitive dependency to it and therefor get no hint.
That raises some new questions:
It seems that org.eclipse.help.ui plugin causes the problem, but we need it in our application. Is this a possible bug? Are there alternatives?
Why does eclipse editor not show the problem if I only have a transitive dependency to javax.xml plugin? Also a possible bug?
I found a workaround for this problem: When using a target definition (*.target file) instead of the Running Platform (automatic target definition of the Eclipse IDE) the error does simply not occur! I don't know exactly what the difference is between these two targets, since they both contain the "javax.xml" bundle. But when using the target file the "javax.xml" bundle is not added to the product file when automatically adding the dependencies and it does not complain later on that this bundle is needed "javax.xml". Somehow when using the target file the "javax.xml" is simply not needed and then no error occurs.
I think there is a bug in Eclipse RCP, that causes this problem when using the Running Platform. But I suggest using a target definition file anyways, since this brings a lot of other advantages.
I have a library compiled with jdk7. Now, I want to import it in a jdk9 module.
We are using maven to manage the dependencies, but after adding the library into the dependency. We still can’t find the classes in the library. But if we remove the module-info.java, everything is ok.
Here is the problem: we have to deliver a jdk9 module, but we have a lot of jdk7 library dependencies. Is it possible? If it is, how? If it isn’t, is there any alternative way?
package is declared in the unnamed module, but the jdk9 module doesn’t read it it says that your explicit module (which contains module-info) tries to access something in classpath, but in jdk9 it`s forbidden. Instead you can move your jar from classpath to module-path and make it automatic module which can refer both classpath and explicit modules
I'm getting below error in STS:
The type org.springframework.core.env.EnvironmentCapable cannot be resolved. It is indirectly referenced from required .class files
This sounds like a transitive dependency issue. What this means is that your code relies on a jar or library to do something - evidently, you depend on Spring framework code. Well, all that Spring code also depends on libraries and jars.
Most likely, you need to add the corerctly versioned org.springframework.core jar to your classpath so that the EnvironmentCapable class can be found when your IDE attempts to build your project.
This might also be a jar collision issue as well, although that sounds less likely. When an application experiences jar collision (also known as "dll hell"), the compiler is finding multiple jars and classes with the same fully-qualified name. For example, let's say you added Spring to your classpath, along with the entire Tomcat server library. Well, those two jars may contain the same exact named classes, maybe the same version, maybe different versions. But either way, when the compiler looks for that EnvironmentCapable class, it finds two (in this contrived example) - one in the Spring jar and one in the Tomcat jar. Well, it doesn't know which one to choose, and so it throws a ClassDefNotFoundException, which would/could manifest itself as the error you experienced.
I faced same error while i work with spring security on spring-security-config.i jsut deleted that jar in maven repo and gave maven->update Project in eclipse.
it is resolved.Please try it once.
From command line, run "mvn clean install", you'll see project failed and you'll see artifacts in the logs that cause such a problem.
After that, remove artifacts from .m2/repository, then maven update from eclipse.
To avoid jar collision, make sure you declare your dependency versions under the properties tag in the aggregate pom.xml, and use the property name as a placeholder throughout the project. For example 4.2.5.RELEASE in the parent pom, and then in the child modules just use ${spring.version} instead of 4.2.5.RELEASE. This way you can avoid having two different versions of the same library on the classpath.
Also it is recommended to be consistent with the version of spring dependencies. Use the same version for spring-core, spring-web etc.
If you are using maven, then you can use the maven enforcer plugin to ensure dependency convergence, and avoid further issues with transitive dependencies.
I have a project that I came back to a couple months since last working on and noticed the majority of the external classes I've been importing and using in my project are now invalid and unable to be found. Pic attached
And when I run maven clean install, I get errors along the lines of
java:[141,17] reference to JsonNode is ambiguous, both class org.codehaus.jackson.JsonNode in org.codehaus.jackson and class com.fasterxml.jackson.databind.JsonNode in com.fasterxml.jackson.databind match
There are several errors of this kind, referencing the line numbers that use the classes unable to be imported.
Could these issues be related? If so what's a simple way to just to reinstall the libraries I need to use in the project and get rid of the collisions?
Thanks for any help,
-Adam
If you didn't change anything in the project, the maven build probably picked up a newer version of some dependency in your pom.xml. You probably have some dependencies on the latest release or on version ranges for some artifacts, as described in this question.
My guess is that the dependency on jackson-databind has changed from 2.2.x to 2.3.0, which was released to the maven central repository quite recently (see here). Between 2.2.x and 2.3.0, they moved the class JsonNode into the package com.fasterxml.jackson.databind
If this is the cause of the problem, the build will be more repeatable and consistent if you set specific version dependencies, or at least narrower ranges, in the pom. In the case of jackson-databind, try setting the version to 2.2.3
Check your classes that the compile error is referring to. You probably have some imports like:
import org.codehaus.jackson.*;
import com.fasterxml.jackson.databind.*;
Then later you are trying to use a JsonNode. The compiler is telling you that's "ambiguous" because both of the above imports have a class named "JsonNode". You just need to call out which JsonNode you want by specifying it with the full classpath in your code.
org.codehaus.jackson.JsonNode node = new org.codehaus.jackson.JsonNode();
(Or something like that)
Once your maven build finishes, those other errors will probably go away in your IDE Screenshot.