I have a dependency library which is being pulled in by a library which I have included in my POM.
This transitive dependency has been flagged as an operational risk by a security scan and asked to upgrade it to the latest version. I need to understand how that can be done?
I tried excluding the library from the POM and then declare a direct dependency on the latest version of the same transitive dependency but I get classNotFound exception.
Code elaboration:-
Direct dependency -> hibernate-core
Transitive dependency which as been flagged -> ANTLR 2.7.7
The failed fix that I have tried ->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.18.Final</version>
<exclusions>
<exclusion>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.0ea8</version>
</dependency>
Please suggest a generic approach to replacing a transitive library.
There is no need for exclusions. You can override transitive dependencies in the <dependencyManagement> like:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.0ea8</version>
</dependency>
...
This will override all transitive occurrences of the library with the version you specify.
But this does not protect you from classNotFound exceptions. If you update a library, class names may have changed and your program might break.
Related
I am trying to use a pom file from a existing project and I am getting an error "Cannot resolve org.yaml:snakeyaml:1.15"
What I find out about this error is that the com.datastax.spark:spark-cassandra-connector_2.11:2.5.0 uses a couple dependencies and a couple levels down it is using snakeyaml:1.15 which is quarantined by company proxy. Is there a way to specify for a given maven dependency that I want to use snakeyaml:1.16?
One thing I do not understand is that I look into the reference project that is also using com.datastax.spark:spark-cassandra-connector_2.11:2.5.0, it is using the updated com.datastax.oss:java-driver-core-shaded:4.9.0, which no longer requires snakeyaml:1.15
where as mine uses the old com.datastax.oss:java-driver-core-shaded:4.5.0
Why is it working in that pom? we have the same maven listing version for com.datastax.spark:spark-cassandra-connector_2.11:2.5.0
I see it has some exclusions but none addresses the snake yaml version or any of its parent dependencies.
Is there another section of the pom file that addresses this I am missing? please advise.
My pom
<scala.compat.version>2.11</scala.compat.version>
<spark.cassandra.version>2.5.0</spark.cassandra.version>
<dependency>
<groupId>com.datastax.spark</groupId>
<artifactId>spark-cassandra-connector_${scala.compat.version}</artifactId>
<version>${spark.cassandra.version}</version>
</dependency>
where it goes wrong
however another project is using the correct shaded version com.datastax.oss:java-driver-core-shaded:4.9.0, which eliminates the snake dependency
working pom
<scala.compat.version>2.11</scala.compat.version>
<spark.cassandra.version>2.5.0</spark.cassandra.version>
<dependency>
<artifactId>spark-cassandra-connector_${scala.compat.version}</artifactId>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<artifactId>netty-all</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</exclusion>
</exclusions>
<groupId>com.datastax.spark</groupId>
<version>${spark.cassandra.version}</version>
</dependency>
You add an entry your <dependencyManagement> section of your POM, where you specify the version of snakeyaml that you want.
This will override all transitive version definitions of snakeyaml.
I suggest to switch to the SCC 2.5.2 (or at least 2.5.1) - there were fixes there regarding dependencies, it has driver upgraded to 4.10.0, etc. Another possibility is to use spark-cassandra-connector-assembly instead, with all dependencies included & shaded.
In my pom.xml, I have a SikuliX Jar which has a transitive dependency on jna-platform.
As seen in below image, version 4.5.2 has overrided version 5.4.0.
But i dont understand, how this version is overrided as i have not specified any dependency for jna-platform. I had also verified that no any there dependency is fetching this jar.
Please help me understand why this is happening. Any detailed document is well appreciated.
Related dependencies:-
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>2.0.4</version>
<exclusions>
<exclusion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</exclusion>
</exclusions>
</dependency>
Thanks
Since you were using spring boot, as suggested here (there's also the reason of this behaviour):
java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/SspiUtil$ManagedSecBufferDesc #882
you can change your order of dependencies, or specify the exact version, like this:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.4.0</version>
</dependency>
or add this property:
<jna.version>5.4.0</jna.version>
Google sheet quickstart
While following this link - https://developers.google.com/sheets/api/quickstart/java
I got this:
Exception in thread "main" java.lang.NoSuchMethodError:
com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient$Builder.setBatchPath(Ljava/lang/String;)Lcom/google/api/client/googleapis/services/AbstractGoogleClient$Builder;
at
com.google.api.services.sheets.v4.Sheets$Builder.setBatchPath(Sheets.java:3143)
at com.google.api.services.sheets.v4.Sheets$Builder.(Sheets.java:3122)
at
com.pansari.promoter.service.SheetQuickStart.main(SheetQuickStart.java:70)
Specifications:
Java version (java -version) 1.8
OS Mac
POM changes:
com.google.apis
google-api-services-sheets
v4-rev516-1.23.0
com.google.api-client
google-api-client
1.23.0
com.google.oauth-client
google-oauth-client-jetty
1.23.0
Can anyone help?
I spent an embarrassing amount of time on this problem, so wanted to leave a tip. The issue with setBatchPath is that it was introduced in google-api-client 1.23.0 and later. I was including the latest builds of google-api-client in my gradle.build file, BUT there were overrides elsewhere in the project that forced the usage of google-api-client 1.22.0 which was breaking the code.
If you're having this problem, try the following:
Check what version of jar is in your build directory build/dependency for example.
Run gradle dependencyInsight --dependency com.google.api-client to see what gradle is doing if you're doing it
The fix for me was adding the following to my build.gradle in the library project and the service that was consuming the library.
dependencyManagement {
dependencies{
dependency 'com.google.apis:google-api-services-sheets:v4-rev607-1.25.0'
dependency 'com.google.api-client:google-api-client:1.25.0'
}
}
The new version of your jars do not contain the method you are trying to call. Read the API for these packages to see how they should be used differently from the previous versions.
Use these dependencies in your project:
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-sheets</artifactId>
<version>v4-rev1-1.21.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.30.4</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-java6</artifactId>
<version>1.30.4</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.30.4</version>
</dependency>
</dependencies>
You can check all the current official dependencies versions by Google HERE.
Check your dependency tree of your project using below command.
mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=truemvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=true
Check different versions of google-api-client jar is and include only 1.23.0 version and exclude other version as below. It should work.
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-dataflow</artifactId>
<version>v1b3-rev207-1.20.0</version>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
</exclusion>
</exclusions>
</dependency>
Check dependency tree of your project using below command
mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=truemvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=true
and include 1.23.0 version of google-api-client and exclude other versions as below.
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-dataflow</artifactId>
<version>v1b3-rev207-1.20.0</version>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
</exclusion>
</exclusions>
</dependency>
dependencies for gradle
implementation 'com.google.api-client:google-api-client:1.33.0'
implementation 'com.google.apis:google-api-services-drive:v3-rev20211107-1.32.1'
implementation 'com.google.http-client:google-http-client-gson:1.19.0'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.3.0'
I am using spring-boot 2.0.3.RELEASE. When I am clicking on "show Effective POM" option by using IntelliJ IDEA, it loads Effective POM. And there I can see a few dependencies that my client don't want to have at there side.
Is there any way to tell Maven not to include these dependencies? How can we exclude dependencies from effective poms?
Maven provides a way to exclude dependencies with the exclude tag
Here is an example taken from the documentation website https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The idea is to locate parent dependencie from where you are getting deps you don't want and add an exclusion tag.
If they are needed in runtime you can specify the scope to provided
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
That will tell maven to use the deps to compile but not no include them in the target package, and they will be provided in the production environment by the JVM executing the code.
Hope this helps
I realised that one of my projects uses slf4j 1.5.8 and Hibernate uses slf4j 1.6. While building with Maven it downloads both jars but I guess the class files of 1.5.8 are used. So, when I run the program i get following error:
SLF4J: The requested version 1.5.8 by your slf4j binding is not compatible with [1.6]
In pom.xml I have put
<dependencyManagement>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
</dependencyManagement>
The 1.5.8 is part of dependency so it's downloaded on its own.
As you discovered yourself, there are two libraries (Hibernate and some other) transitively importing SLF4J in two different versions. Unfortunately the older version is being picked up by maven (there are some rules which dependency should be chosen by maven in this situation). The solution is to add the exclusion in the dependency that imports older version of SLF4J (com.example:foo-bar is example here):
<dependency>
<groupId>com.example</groupId>
<artifactId>foo-bar</artifactId>
<version>1.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
If you still experience this problem, issue:
$ mvn dependency:tree
Look for 1.5.8 version and exclude it from all libraries importing it.
Excluding is quite unnecessary and maybe quite misleading. Instead, explicitly include the slf4j-api with the desired version in your projects pom file. That's it!
This approach takes advantage of Maven's transitivity rules: the nearest dependency declaration wins.
you can exclude the wrong version with something like this:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.7.ga</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>