import a jdk7 library in jdk9 module - java

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

Related

How to deal with ResolutionException?

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

Specific question concerning "The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml"

I'm in the process of migrating my companies projects from Java 1.8 to OpenJDK 14. Like multiple other people (fe. in this, this or this thread) I've run into some troubles with Java 9 Modularity, specifically with the package org.w3c.dom.
I have already generated the module-info.java and currently both the JRE System Library (OpenJDK 14) and all external JARs are on the Modulepath in the Java Build Path. So I no longer have the error module: <unnamed>.
The actual compile error I get right now is:
The package org.w3c.dom is accessible from more than one module: batik.all, java.xml, xml.apis.ext
BTW I can't just simply delete the JARs batik.all and xml.apis.ext, since other packages of those are used in the project which are not in the JavaSE.
I've also been told by my supervisors to not convert any non-maven projects to maven projects, which I mention since all other references I find to this problem seem to discuss the solution of utilising Maven Dependencies and Excludes.
Now after some analysis I've come to the conclusion that the most effective way for me to get rid of these errors would be to unpack the two JAR files, decompile the packages, delete the duplicate org.w3c.dom from those external JARs and finally recompile the whole thing and pass that custom JAR to the build path.
Does that idea make sense? Would you do it this way if you couldn't use Maven dependencies?
Since we're migrating from 1.8, I've never actually used module-info.java, so perhaps there's a way simpler way of excluding those packages in that file? I'm open for alternative solutions!
Last but not least, if my described solution is the way to go, what would be the best way to unpack and repack those JAR files?
You do not need to decompile/recompile anything, you can simply delete the directory in the JAR file corresponding to the package.

Maven Adding dependency for specific java package

I have two version of the same jar file. (version 1 and 2). My problem is that i want classes in a specific package to use one version and classes in another package to use the other version.Both the packages are under the same maven project.
Tried to add both the jar files as dependencies in the POM, but the second entry overrides the first one and only one version is added as dependency.
Is there a way to achieve this in Maven.?
Think about DLL Hell. The only way you can get various versions of the same class to coexist in a single JVM is to load each using a different class loader, and you don't want to go that way.
Rewrite your code so all of it works with the newest version of the library, or rewrite it so it doesn't need whatever changes in the library require you to use v2, your choice.
Token ugly solution...
Split your project into two modules, where each module uses a different version of the dependency. To avoid the class-loader problems referenced in jwenting's excellent answer, use the Maven Shade Plugin to rename the dependency packages in one of the modules.
See Relocating Classes for an example of doing this.

Indirectly referenced from required .class files

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.

Why doesn't the Java compiler download imported packages?

I'm trying to run a Lucene Java application on my local machine. I get this compilation error:
package org.apache.commons.digester does not exist
because of
import org.apache.commons.digester.Digester;
Isn't the compiler downloading the package from the Internet?
If not, what should I do?
No, the compiler doesn't download packages from the Internet. Some build management tools like Maven do it if you configure them properly and add the package to the project dependencies. But without such a tool you should download the jar manually and put it on the compiler classpath.
If you are using Maven you could download the lib by adding the following dependency:
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>2.1</version>
Else you have to download it here. Then just add the .jar to your Buildpath.
If you are using maven and added this as dependency then it will download it for you. otherwise
You can download it from here , appropriate version. and add it to your app's class path
No the compiler does not download packages from the internet when you import them. The naming convention for packages makes them appear like URLs but they are not and the compiler certainly makes no attempt to download dependencies.
The idea is that if all creators of Java libraries conform to this convention and use their domain name in package names then class name clashes between libraries from different authors can be avoided. However as previously stated this just a naming convention and has relationship to dependency management.
Some build tools like Maven have sophisticated and relatively easy to use dependency management mechanisms. The popular Ant build tool also has this capability through the Ivy dependency manager.

Categories

Resources