How to exclude dependencies from Gradle Version Catalog? - java

I'd like to perform the equivalent to the following declaration:
dependencies {
implementation('commons-beanutils:commons-beanutils:1.9.4') {
exclude group: 'commons-collections', module: 'commons-collections'
}
}
But within the version catalog feature. Something like:
dependencyResolutionManagement {
versionCatalogs {
libs {
library('commons-lang3', 'org.apache.commons', 'commons-lang3').exclude {
// group, module etc
}
}
}
}

From a comment on a somewhat unrelated issue:
https://github.com/gradle/gradle/issues/19517#issuecomment-1012159205
(...) the catalog is purely a list of dependencies to pick from.
So, anything else such as exclusions, you must define them as usual in the dependencies { } block.

There's a simple way to do this, which unfortunately isn't documented:
implementation dependencies.create(libs.commons.beanutils.get()) {
exclude group: 'commons-collections', module: 'commons-collections'
}
Note the get() call - beanutils in this case is an instance of Provider<?> so you need to manually unwrap it.

this is pretty ugly but works 👀
in kotlin for example:
vorbisspi = "com.googlecode.soundlibs:vorbisspi:1.0.3.3"
implementation(libs.mp3spi.get().let { "${it.module}:${it.versionConstraint.requiredVersion}" }) {
exclude("javazoom.spi", "spi")
exclude("junit", "junit")
}

Related

Trying to implement cucumber.api.cli.Main.main()

I have tried to implement the 'cucumber.api.cli.Main' but I get the following error: "No backends were found. Please make sure you have a backend module on your CLASSPATH." Does this mean I am missing a dependency? My Gradle and java code is below.
java code
package cucumber;
import cucumber.api.cli.Main;
import java.io.PrintStream;
public class CucumberRunEngine {
public static void main(String[] args) {
try {
Main.main(
new String[]{
"CLASSPATH:src.main.groovy.cucumber.features.addDeal",
//"-t", "#Daily",
"-g", "cucumber.stepDefinitions",
"-p", "pretty",
"-p", "html:target/HTMLReports/report.html",
"-p", "junit:target/JUNITReports/report.xml",
"-p", "json:target/JSONReports/report.json",
"-m"
}
);
} catch (Exception e) {
PrintStream printer =System.out;
printer.println(e);
for (int element=0;element<e.getStackTrace().length;element++) {
printer.println(e.getStackTrace()[element]);
}
}
}
}
Gradle code
plugins {
id 'groovy'
id 'java-library'
id 'application'
id "se.thinkcode.cucumber-runner" version "0.0.8"
}
dependencies {
//Standard
api "org.codehaus.groovy:groovy-all:${groovyVersion}"
api "com.reuters:corejavalib:${coreJavaLibVersion}"
api "com.oracle:ojdbc7:${ojdbc7Version}"
implementation "commons-io:commons-io:${commonsIoVersion}"
implementation "commons-lang:commons-lang:${commonLangVersion}"
//JUnit
implementation "junit:junit:${jUnitVersion}"
// implementation("org.junit.platform:junit-platform-suite")
compileOnly "org.testng:testng:${testNGVersion}"
//Cucumber
compileOnly "io.cucumber:cucumber-java:${cucumberVersion}"
compileOnly "io.cucumber:cucumber-java8:${cucumberVersion}"
compileOnly "io.cucumber:cucumber-junit:${cucumberVersion}"
compileOnly "io.cucumber:cucumber-groovy:${cucumberGroovyVersion}"
compileOnly "io.cucumber:cucumber-gherkin:${cucumberVersion}"
compileOnly "io.cucumber:cucumber-jvm-groovy:${cucumberGroovyVersion}"
compileOnly "io.cucumber:cucumber-junit-platform-engine:${cucumberVersion}"
implementation "io.cucumber:cucumber-core:${cucumberVersion}"
}
application{
mainClass="cucumber.CucumberRunEngine"
}
repositories {
}
Gradle.properties
# versions of dependencies used in this project defined here
groovyVersion=2.5.7
commonCliVersion=1.3.1
commonsIoVersion=2.6
commonLangVersion=2.6
#JUnit
jUnitVersion=4.8
testNGVersion=7.4.0
jUnitPlatformSuiteVersion=1.9.0
#Cucumber
cucumberVersion=7.4.0
cucumberGroovyVersion=6.10.4
ojdbc7Version=12.1.0.2
coreJavaLibVersion=3.5.21.9
Thank you for any help in advance :)
Your project setup is a bit peculiar. There are too many parts that simply don't belong. For example as a result of using compileOnly you're not including the code you need at runtime. And so Cucumber complains it can't find cucumber-java (a backend).
Now you may have already noticed this and scoped cucumber-core to implementation for this reason. But this suggests you're fixing one error at a time rather then building a fundamental understanding of the tools you use.
So it's worth reading how Gradle does dependency management for you:
https://docs.gradle.org/5.3.1/userguide/java_plugin.html#sec:java_plugin_and_dependency_management
A minimal example can be found in the skeleton project. It is not tailored to your needs, but it should be a good starting point.
https://github.com/cucumber/cucumber-java-skeleton
plugins {
java
}
dependencies {
testImplementation(platform("org.junit:junit-bom:5.9.0"))
testImplementation(platform("io.cucumber:cucumber-bom:7.6.0"))
testImplementation("io.cucumber:cucumber-java")
testImplementation("io.cucumber:cucumber-junit-platform-engine")
testImplementation("org.junit.platform:junit-platform-suite")
testImplementation("org.junit.jupiter:junit-jupiter")
}
repositories {
mavenLocal()
mavenCentral()
}
tasks.withType<Test> {
useJUnitPlatform()
// Work around. Gradle does not include enough information to disambiguate
// between different examples and scenarios.
systemProperty("cucumber.junit-platform.naming-strategy", "long")
}

is it possible to force java module dependencies to use specify version [duplicate]

I have a distributes projects with different sub-projects and I want to accomplish the following:
(root)
client
module A
module B
module C
model
I want to put
protoc {
artifact = 'com.google.protobuf:protoc:3.5.0'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.7.0"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
} }
dependencies {
compile "com.google.api.grpc:proto-google-common-protos:1.0.0"
compile "io.grpc:grpc-netty:1.7.0"
compile "io.grpc:grpc-protobuf:1.7.0"
compile "io.grpc:grpc-stub:1.7.0"
}
for module A, B and C.
For now I have the following in my root build.gradle
subprojects{
apply plugin: 'java'
sourceCompatibility = 1.8
group 'project'
version '0.0.1-SNAPSHOT'
jar {
manifest {
attributes 'Main-Class': "com.project.${project.name}.App"
}
doFirst {
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
}
}
So every sub-project use java plugin, and has the defines dependencies and jar task.
How can I only put the first block for some sub-projects ?
I tried using a variable like in Multi-project Builds - Gradle but I couldn't access it in subprojects block.
Thank you in advance. I'm really interested in using Gradle correctly and it's a bit hard to get into it outside of simple Android/Java projects. Feel free to include any documentations I should read :)
Edit:
Thank you. I wouldn't have posted here if I hadn't search before. Apparently I was missing the keyword "subset" who would have gave me the solution you linked.
A solution is described here: https://discuss.gradle.org/t/configure-only-subset-of-subprojects/5379/3
You can run configure() with a list of projects.
project.ext {
subprojectList = subprojects.findAll{
it.name == 'subprojectA' ||
it.name == 'subprojectB' ||
it.name == 'subprojectC'
}
}
configure(project.subprojectList) {
// insert your custom configuration code
}
or
configure([project(':a'), project(':b'), project(':c')]) {
// configuration
}

Issue with importing a Gradle project for XNAT - unresolved type

I trying to import a Gradle project for XNAT for the first time using Eclipse 2018-12. I created the project, right clicked, chose Gradle then Existing Gradle Project. After the import completed there is an error with SimpleUploadPlugin.java - "The type org.apache.ecs.ConcreteElement cannot be resolved. It is indirectly referenced from required .class files". I have checked and I have the commons-lang3-3.8.1.jar.
What do I need to do to resolve this issue please?
My build.gradle dependencies are:
// TODO: This is a pretty minimal set of dependencies, so don't worry if you need to add more.
dependencies {
implementation("org.nrg.xnat:web") {
transitive = false
}
implementation("org.nrg.xnat:xnat-data-models") {
transitive = false
}
implementation("org.nrg.xdat:core") {
transitive = false
}
implementation "org.nrg:prefs"
implementation "org.nrg:framework"
implementation("turbine:turbine") {
transitive = false
}
implementation("org.apache.velocity:velocity") {
transitive = false
}
implementation("stratum:stratum") {
transitive = false
}
implementation "log4j:log4j"
implementation "io.springfox:springfox-swagger2"
compile group: 'ecs', name: 'ecs', version: '1.4.2'
}
Another option is to change the dependency configuration for org.nrg.xnat:web from compile or implementation to compileOnly. This lets you declare fewer dependencies for your plugin because you can allow transitive dependencies. The ECS dependency comes from classes in XNAT itself, so allowing the transitive dependencies means you don't have to declare everything that might be indirectly referenced. I just made this change in the XNAT LDAP authentication plugin and went from this:
implementation("org.nrg.xnat:web") {
transitive = false
}
implementation("org.nrg.xnat:xnat-data-models") {
transitive = false
}
implementation("org.nrg.xdat:core") {
transitive = false
}
implementation("org.nrg:prefs") {
transitive = false
}
implementation("org.nrg:framework") {
transitive = false
}
implementation "org.springframework:spring-web"
implementation "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-ldap"
implementation "org.apache.commons:commons-lang3"
implementation "org.hibernate.javax.persistence:hibernate-jpa-2.1-api"
implementation "com.google.guava:guava"
implementation "org.slf4j:slf4j-api"
implementation "log4j:log4j"
implementation "org.springframework.security:spring-security-web"
implementation "javax.servlet:javax.servlet-api"
compileOnly "com.google.code.findbugs:jsr305"
compileOnly "org.apache.ivy:ivy:2.4.0"
compileOnly("stratum:stratum") {
transitive = false
}
To this:
compileOnly "org.nrg.xnat:web"
compileOnly "org.springframework.security:spring-security-ldap"
compileOnly "org.slf4j:slf4j-nop"
If you run this:
$ ./gradlew dependencies
You'll see that ecs:ecs:1.4.2 gets pulled in through a number of transitive dependencies.
org.apache.ecs.ConcreteElement is from the Apache Element Construction Set (ECS) and for example contained in ecs-1.4.2.jar.
To resolve the issue add a dependency to your build.gradle file like the following:
// https://mvnrepository.com/artifact/ecs/ecs
compile group: 'ecs', name: 'ecs', version: '1.4.2'

Exclude Dependency Gradle

I have a problem of conflicting dependencies.
The two jars are:
net.sf.jasperreports:jasperreports:6.4.1
com.connectifier.xero:client:0.13
Which both seem to be loading different versions of the same dependency:
org.bouncycastle.
I can't seem to get it to work no matter what I try.
Have been trying something like this:
configure(globalModule) {
dependencies {
compile('net.sf.jasperreports:jasperreports:6.4.1')
compile('com.lowagie:itext:2.1.7') {
exclude group: 'org.bouncycastle'
}
compile('com.connectifier.xero:client:0.13') {
exclude group: 'org.bouncycastle'
}
}
The error I keep getting is:
SecurityException: class "org.bouncycastle.asn1.pkcs.RSAPublicKey"'s signer information does not match signer information of other classes in the same package
The app will run fine if I do not import JasperReports, but I definitely need this.
I have resolved it! The normal method of exclude in gradle was not working and the workaround was as follows:
configure(globalModule) {
dependencies {
compile('net.sf.jasperreports:jasperreports:6.4.1')
compile('com.connectifier.xero:client:0.13')
compile('com.lowagie:itext:2.1.7')
}
configurations {
compile {
exclude group: 'org.bouncycastle'
exclude module: 'bcprov-jdk14'
}
}
task enhance(type: CubaEnhancing)
}

Add provided dependency to test classpath using Gradle

I've provided dependency scope configured like below. My problem is, the provided dependencies are not visible during runtime in tests. How can I configure this to keep the dependencies provided but available on the test classpath?
apply plugin: 'java'
configurations {
provided
}
sourceSets {
main {
compileClasspath += configurations.provided
}
}
dependencies {
provided 'com.google.guava:guava:18.0'
provided 'org.apache.commons:commons-lang3:3.3.2'
// Tests
testCompile 'junit:junit:4.11'
testCompile 'org.assertj:assertj-core:1.7.0'
// Additional test compile dependencies
testCompile 'joda-time:joda-time:2.2'
}
One solution is to add the dependency like the joda-time library with testCompile scope, but I don't want to duplicate any entries. I'm sure it can be achieved with proper configuration.
Two ways to do this. First, have the testRuntime configuration extend from provided.
configurations {
provided
testRuntime.extendsFrom(provided)
}
Second, you could add the provided configuration to the classpath of your test task.
test {
classpath += configurations.provided
}
Fixed with one additional line in configurations. Don't know if it's the best and a proper solution but works as intended.
configurations {
provided
testCompile.extendsFrom(provided)
}
my case
withType<Jar> {
enabled = true
isZip64 = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveFileName.set("$project.jar")
from(sourceSets.main.get().output)
dependsOn(configurations.compileClasspath)
from({
configurations.compileClasspath.get().filter {
it.name.endsWith("jar")
}.map { zipTree(it) }
}) {
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
}
}

Categories