How to resolve external dependency conflict in gradle - java

I am getting following conflicts for okio library in my sprint boot project.
I am not not sure how to read this. Specifically:
What does conflict actually mean here. What is conflicting with what?
Why is 1.6.0 is conflicting with 1.6.0
What does Scopes mean (6 scopes , 4 scopes) etc..
How do I resolve this in my gradle project. Current in my build.gradle I have
implementation "org.apache.commons:commons-vfs2:2.9.0"
implementation 'io.fabric8:kubernetes-client:6.3.1'
My server fails to start with a NoSuchFieldError within a class in Okio library. How can I go about resolving this? None of this is my direct code issue is happening in the okio which is the transitive dependency of above two libraries.

It is having same library but two version of it on classpath, so at run time any one would be picked.
And if the version has some breaking changes, it won't work. You have to put a constraint to have only one version.
You can refer to How Gradle handles conflicts? for more information.

Related

Problem with Eclipse when using Java 11 and Cassandra Spring Unit possibly along with lombok and gradle

So I ran into a problem with a project. Where Eclipse would say that java.util.* has an import error The package java.util is accessible from more than one module: <unnamed>, java.base
I dug around a lot it appears that for some reason no one else is really having this issue. Everyone in our office was. They have told me though that a RC version of Eclipse from 2018 I think Sept works, but that is the only one they can get it to work in. I'll try to post the real version later. So I searched a lot and then started playing with the gradle file for includes. And found that the problem only exists if I include the Cassandra-unit-spring testCompile requirement and because of that it only causes a problem on the test case side.
My assumption is that this is somehow a bug with eclipse as gradle itself has no problem with it. As well as intelij. Let me know what else I can provide here to narrow this down further.
Eclipse Build id: 20190917-1200
Eclipse with Lombok Lombok v1.18.10
Gradle 5.6.4
Oracle JDK 11.0.5
tried cassadnra-unit-spring versions 3.5.0.1 - 3.11.x
Also using spring boot 2.1.3.release
Thanks.
I have excluded all (transitive) dependencies of cassandra-unit and re-included them one by one. Eventually, I found out that the library com.boundary:high-scale-lib, i.e., a transitive dependency included by org.apache.cassandra:cassandra-all, is responsible for the import errors.
The library is not Java 9+ ready, since it uses a java.base package name, i.e., java.util. This is not allowed. Unfortunately, you cannot exclude this transtive dependency, since it is required.
I found out that the release version of Eclipse 4.10 does not indicate errors in projects using the library. This is probably a UI bug in newer Eclipse versions, since I can compile and build my application with Gradle without any errors.
You can try this Eclipse version.
Thank you very much for your hard work Sincostan
So with the information you provided, if you put into your build.gradle file the inclusion of the cassandra unit test like this
testImplementation ('org.cassandraunit:cassandra-unit-spring:3.11.2.0') {
exclude module: 'high-scale-lib'
}
This allowed it to work in my case. you would of course need to use your own version etc. This is with Gradle 6.3 at this time.

How does Gradle resolve library version conflict?

In a setup like this:
Project
-ModuleA
implementation lib:1.1
implementation project(:ModuleB)
-ModuleB
api lib:1.2
-ExternalJar1
-lib1.3
-ExternalJar2
-lib1.4
How does Gradle determine what lib version to select? As per this SO answer, version 1.4 will be selected because it's the highest version and we have not specified "any specific constraints for transitive dependencies resolution". If that's correct, wouldn't ModuleA code break if it's not expecting a newer version? How can I fix that?
Do external libraries (imported jars) live in a closed sandbox - neither exposing their dependencies to project's classpath, nor using project dependencies in their classpath?
Assuming version 1.3 and 1.4 are not compatible, I can't even force one version as suggested in this SO post, what option do I have to fix this setup?

Provided Maven Dependency which does not exist in repository but in container

I have to use a library so I looked it up in our repository and added it to the dependencies. When starting the Weblogic server I got a DeploymentException (Ambiguous Bean Name).
I found out that this means that I try to register Beans with the same name twice or more.
Then I found out that this library is already provided by the server (JEE Container). Therefore this exception makes sense. I then changed the scope of the dependency to provided and the version to the one provided by the container.
But then I got a build error because the dependency can't be resolved with that version. I checked our repo manually and saw that this is true.
version provided by container: 1.0.4
version existing in repo: 1.0.7
How can I resolve this issue? I just want to tell maven that it should use the library which will exist when deployed. And ignore the fact that it's not available during compilation. (If this is even possible)
I think you misunderstood some aspects of "provided".
Giving a dependency as "provided" means that it is only used for compilation but not packaged into your war/ear. This implies that it does not make sense to specify a dependency as "provided" if it does not exist in the repository.
The usual way to solve your problem would be to specify the dependency with version 1.0.7 and make sure that you do not call any class/method that is not present in version 1.0.4.
Your application will then compile against 1.0.7 but runs with 1.0.4 which is fine in most cases (note that Java cannot check or know the versions of the included jars - the only risk is that 1.0.7 has different interfaces than 1.0.4 which is unlikely if only the last part of the number changed).

How can I prevent code from using wrong version of some dependency?

I have a project which depends on a JAR file. The version of this JAR changes often and we are having a hard time trying to ensure we are using the correct one. It is also causing problems when investigating bugs: which version of JAR contains the bug. Some programmers may forget to update corresponding dependencies and include 2 versions of this JAR inside the project, so that an old version may be found by the classloader.
A question is how to account for this issue.
I have a following plan:
1) When an error occurs log the JAR name I am working with to ensure it is a correct version. I plan to use something like
this.getClass().getResource(someResourceINeedFromThatJar).getFile()
2) I can write a test to account for this. But I don't know how I can run a test AFTER the package phase of my Maven build
3) Maybe you can suggest something else for this?
Well, We have same scenario and solved issue by using maven dependencyManagement
It does two things.
Set a default version for dependencies in submodules/child projects
override the version of transitive dependencies
it does override a specified value in a transitive dependency.
The enforcer plugin does not ignore the dependencyManagement. But is unable to recognize the discrepancy since the transitive dependency's version was altered before it went to work.
Here is a nice article : You can go through it:
http://andydennie.com/2012/08/02/maven-enforcer-plugin-vs-dependencymanagement/
And another source: http://maven.apache.org/enforcer/maven-enforcer-plugin/

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.

Categories

Resources