I am using gradle 3.2.1. I have a framework that pulls up dependencies (newer version). But the problem is that my project already has these dependencies (old version) and I don't want to change their version. And the required framework cannot work without a new version. And my question is, can you restrict the built-in dependencies of the framework only for it? and use the same version for my application? is there such a possibility in gradle?
An example of how i exclude the loading of components, but i need to leave them only for this dependency:
compile(group: 'io.javalin', name: 'javalin', version: '4.1.1') {
exclude group: 'org.eclipse.jetty'
exclude group: 'org.eclipse.jetty.websocket'
}
Related
So I've seen other posts (eg. Can't use hbase-shaded-client jar because of its internal dependency to log4j-1.2.17(CVE-2019-1757)) stating that they have a way to exclude the transitive dependency of log4j:log4j:1.2.17 however if I run ./gradlew app:dependencies I can still see that the transitive dependency exists.
I have tried referring to the following migration doc https://logging.apache.org/log4j/2.x/manual/migration.html but Im not sure if this is just transferring the calls over from log4j 1.x over to 2.x at runtime or if its supposed to update the transitive dependency all together. I tried even excluding the transitive dependency and using slf4j instead in my build.gradle file like so:
compile ('custom-library-that-I-cant-change-code-in'), {
exclude group: 'log4j', module: 'log4j'
}
// https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j
implementation 'org.slf4j:log4j-over-slf4j:1.7.35'
How can I make sure if this is even working, or at least not using that older log4j:log4j:1.2.17 or am I going about this all wrong and there is an easier way of doing this
To answer you first question the following exclude wasn't working for me as well,
compile ('custom-library-that-I-cant-change-code-in'), {
exclude group: 'log4j', module: 'log4j'
}
try this in your build.gradle it should work
configurations {
compile.exclude group: "log4j", module: "log4j"
}
I have a problem with Gradle. I want to use an externally provided Jar: itext-2.1.7.js6.jar, it is a patched version used by JasperReports.
In the project structure, I have a /libs directory, containing 2 files: fonts.jar and itext-2.1.7.js6.jar
Part of my gradle.build file looks like this:
compile fileTree(dir: 'libs', include: ['*.jar'])
implementation group: 'net.sf.jasperreports', name: 'jasperreports', version: '6.7.1'
implementation group: 'net.sf.jasperreports', name: 'jasperreports-functions', version: '6.8.0'
implementation group: 'joda-time', name: 'joda-time', version: '2.9.9'
//implementation group: 'hu.blackbelt.bundles.itext', name: 'com.lowagie.itext', version: '2.1.7-1'
The last dependency is commented out cause I want to use the external JAR instead of the original iText.
When I am trying to run my app I get:
BUILD FAILED in 0s
1 actionable task: 1 executed
Could not find com.lowagie:itext:2.1.7.js6.
Required by:
project : > net.sf.jasperreports:jasperreports:6.7.1
What am I doing wrong? Everything is fine with my fonts.jar, so I think that it should be the same with iText, but it isn't...
As can be seen in the pom file of jasperreports, there is an explicit dependency on com.lowagie:itext:2.1.7.js6 which can also be found in a specific Jasper Reports repository
The reason this works transparently in Maven is that Maven will use the repositories defined in a pom file, while Gradle will not use them, as they could be a source of insecurity.
You have two options:
Add that repository, potentially using repository filtering to only serve these artifacts from there and then remove the file from libs
Add an exclude to jasperreportsso that it no longer tries to fetch that dependency. And instead the runtime code will use the version found in libs. You just forget about transitive dependency management in this case, for example when upgrading jasperreports and getting (or not) an updated version from their dependency declaration.
I have conflict problem with dependencies.
My project has two dependencies like this:
dependencies {
provided group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
compile files('path/to/ABC.jar')
}
ABC.jar has its own dependency to javax.servlet:servlet-api:
dependencies {
provided group: 'javax.servlet', name: 'servlet-api', version: '2.5'
}
Here is the problem I am dealing with; I need to use ServletContext interface which is provided by both servlet-api libraries and the compiler uses wrong one.
Gradle auto-resolves version conflicts as described here.
But in my case it doesn't help, because it only works when a dependency has two different versions. In this case; although it's a newer version issue, the name has changed from javax.servlet:servlet-api to javax.servlet:javax.servlet-api. So gradle doesn't auto-resolve this conflict, because it doesn't seem to be a version issue.
The thing I tried was using excluding transitive dependency as described here.
compile files('path/to/ABC.jar') {
exclude group: 'javax.servlet'
}
But it didn't work, it seems exclude doesn't work on local 'jar' files.
Now, I don't know what else to do.
How can I exclude a dependency of a dependency which is added as a local file?
(If the first question doesn't have any answer yet) How can I say to the compiler to use the correct ServletContext interface?
compile files('path/to/ABC.jar') is a file dependency, a file dependency does not have any dependency information, so it does not introduce transitive dependencies. If this ABC.jar is a "fat" jar that has the dependency-classes included in the JAR, it is not suited for usage in something like Gradle, Maven or Ant/Ivy that is supposed to handle the dependencies. You would have to use a proper "thin" version of the dependency with the dependencies properly declared, or you need to "repackage" that JAR in your build script to exclude the dependency classes you don't want to pull in. No dependency management can do this for you.
You can execute gradlew dependencyInsight --configuration runtime --dependency javax.servlet:servlet-api or gradlew dependencies --configuration runtime to find out where the dependency really comes from.
Actually your example should not even compile if I see it correctly, because it should most probably be
compile files('path/to/ABC.jar'), {
exclude group: 'javax.servlet'
}
or
compile(files('path/to/ABC.jar')) {
exclude group: 'javax.servlet'
}
But as I said, with a local file dependency there are no transitive dependencies, so an exclude does not make sense at all anyway.
To make the Gradle version conflict magic work, you can simply tell Gradle that those libraries are actually the same library just with different coordinates by using a module replacement like
dependencies {
modules {
module('javax.servlet:servlet-api') {
replacedBy 'javax.servlet:javax.servlet-api'
}
}
}
Then Gradle sees them as the same library and can do its version conflict resolution magic. Whether the library that needs the old version still works with the new version is a different topic that you have to check and / or try yourself. This like always depends on whether the new version is backwards compatible to the old version.
I have no way to test this now, but I believe your syntax is wrong. I have some examples here that look different, in your case it would be:
compile(files('path/to/ABC.jar')) {
exclude group: 'javax.servlet'
}
As I say, I cannot test it now, check if it helps and give a comment.
I'm experiencing an issue where multiple versions of the same class are showing up in my classpath. The class in question is javax.ws.rs.core.UriBuilder. The version I want to use is brought in by javax.ws.rs:javax.ws.rs-api:2.0.1. However, we also use the Jira rest client library which has a dependency on the older version of jersey (com.sun.jersey:jersey-core) which has included the java.ws packages bundled in it's jar.
Here is an example snippet from the build file:
dependencies {
compile 'com.atlassian.jira:jira-rest-java-client-core:2.0.0-m31'
compile 'javax.ws.rs:javax.ws.rs-api:2.0.1'
compile 'org.glassfish.jersey.core:jersey-client:2.17'
}
I can't remove com.sun.jersey:jersey-core as it uses different package name from the new version and would cause class def not found exceptions in the Jira client.
As far as I can tell, my options at this point are:
Revert to using Jersey 1.x and it's implementation of jsr311
Somehow have gradle exclude the javax.ws package from the old jersey client.
I'd like to keep using the newer version of jersey so #2 would be my ideal solution but I'm not sure if it's even possible. Does anyone know how to go about this? If that's not possible, I'm open to other suggestions.
You can exclude an transitive dependency module like this:
compile ('org.glassfish.jersey.core:jersey-client:2.17') {
exclude group: 'javax.ws.rs'
exclude module: 'javax.ws.rs-api'
}
ref: 50.4.7 here
I found out that com.sun.jersey:jersey-core:1.19 doesn't bundle the javax.ws.rs class files and instead lists them as a compile-time dependency. Adding this snippet to my build.gradle fixed the issue.
configurations.all {
resolutionStrategy {
// For a version that doesn't package javax.ws
force 'com.sun.jersey:jersey-core:1.19'
}
}
exclude the group and module as below.
Ex :
implementation('org.apache.httpcomponents:httpclient:4.5.13') {
exclude group: 'commons-codec', module: 'commons-codec'
}
Say I want to add guice-assistedinject as a dependency in my project. It specifies the guice artifact as a dependency itself. How do I tell it to use the no_aop version of guice?
I know I can do the following, but can I do it in one step without excluding the guice module?
dependencies {
compile (group: 'com.google.inject.extensions', name: 'guice-assistedinject', version: '3.0') {
exclude module: 'guice'
}
compile group: 'com.google.inject', name: 'guice', version: '3.0', classifier: 'no_aop'
}
There is no simpler solution. You can shorten the code by using short dependency notation (e.g. "com.google.inject:guice:3.0:no_aop").