Add provided dependency to test classpath using Gradle - java

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")
}
}

Related

Gradle Not Finding Method Implementation for Arguments

I am trying to build a simple maven library and I can't get it to build. I am using Gradle Groovy and Kotlin Multiplatform Library in IntelliJ IDEA.
I haven't even been able to begin coding since my dependencies wont load. I am very new to all this so bare with me.
This is my build.gradle
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.7.10'
}
group = 'me.me'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies{
implementation platform("io.cucumber:cucumber-bom:7.1.0")
implementation 'io.cucumber:cucumber-java'
implementation 'io.cucumber:cucumber-junit-platform-engine'
implementation 'io.cucumber:cucumber-junit'
implementation 'io.cucumber:cucumber-spring'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = '1.8'
}
withJava()
testRuns["test"].executionTask.configure {
useTestNG()
}
}
sourceSets {
commonMain {
}
commonTest {
dependencies {
implementation kotlin('test')
}
}
}
}
and this is the error I am getting
Build file '/Users/Me/Documents/GitHub/Project-Tools/build.gradle' line: 13
A problem occurred evaluating root project 'Project-Tools'.
> Could not find method implementation() for arguments
[DefaultExternalModuleDependency{group='io.cucumber', name='cucumber-bom', version='7.1.0', configuration='default'}]
on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
I even tried commenting out each dependency one at a time so see if any work and none did
EDIT: Also I am on a Mac

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
}

Gradle control transitive from dependency build.gradle

I'm not sure if this is feasible, but wanted to get some comments/solution for the problem.
I'm creating a new dependency com.example:app-dep:1.0.1 will be used in com.example:app as compile dependency.
app-dep having a dependency io.undertow:undertow-core:2.0.1.Final which I don't want in com.example:app project, because I'm excluding the class file from com.example:app-dep related to undertow because the class requires on development time but not required in production.
When I add com.example:app-dep:1.0.1 in com.example:app I want to exclude io.undertow:undertow-core:2.0.1.Final.
But I want to control that from com.example:app-dep:1.0.1 maybe enable in future.
Some gradle I tried
TRY 1
app-dep - build.gradle
dependencies {
implementation('io.undertow:undertow-core:2.0.1.Final') {
transitive = true
}
implementation('io.undertow:undertow-servlet:2.0.1.Final') {
transitive = false
}
}
jar {
from sourceSets.main.allSource
excludes = ['com/example/ExampleServer**', 'public']
}
production-app build.gradle
using spring-boot-gradle-plugin bootRepackage
buildscript {
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.12.RELEASE"
}
}
dependencies {
compile 'com.example:app-dep:1.0.1'
}
OUTPUT: Still pulling and adding io.undertow:undertow-core:2.0.1.Final in production spring-boot jar
TRY 2
Using profiles
dependencies {
compile 'org.apache.commons:commons-lang3:3.4'
testCompile 'org.mockito:mockito-core:3.1.0'
testCompile 'org.powermock:powermock-module-junit4:1.6.6'
testCompile 'org.powermock:powermock-api-mockito:1.6.6'
if(isDev) {
implementation 'io.undertow:undertow-core:2.0.1.Final'
}
}
OUTPUT: Class inside app-dep throwing compilation error saying the following when I do ./gradlew build
Undertow server = Undertow.builder().addHttpListener(8081,
"localhost").setHandler(routingHandler).build();
^
symbol: variable Undertow
location: class ExampleServer
26 errors
What I can do but I don't want
In production-app build.gradle
dependencies {
compile('com.example:app-dep:1.0.1') {
exclude(module: 'com.example.app-dep')
}
}
Because I want to control that from app-dep

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)
}

JUnit 5 under Gradle with multiple source sets

I've got a project I'm putting together that I want to use JUnit 5 for. I've got this working fine for Unit Tests already.
I do however have multiple test source sets - I've got an additional one for Acceptance Tests. I'm struggling to work out how to get JUnit 5 to run the Unit Tests - defined in src/test - in one task and the Acceptance Tests - defined in the "acceptanceTest" sourceSet and located in "src/acceptance" - in another task.
I have previously got this working with JUnit 4 and Cucumber, but the JUnit 5 plugin doesn't seem to want to work like this.
build.gradle:
buildscript {
ext {
jackson_version = "2.9.0.pr4"
// IntelliJ needs M4
junitJupiter_version = "5.0.0-M4"
junitPlatform_version = "1.0.0-M4"
kotlin_version = "1.1.3-2"
slf4j_version = "1.7.25"
spring_version = "4.3.10.RELEASE"
springBoot_version = "1.5.4.RELEASE"
springBootAdmin_version = "1.5.2"
runAcceptance = System.properties['noAcceptance'] == null
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "com.github.ben-manes:gradle-versions-plugin:0.15.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
classpath "org.junit.platform:junit-platform-gradle-plugin:$junitPlatform_version"
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBoot_version"
}
}
plugins {
id "com.github.ben-manes.versions" version "0.15.0"
}
apply plugin: "com.github.ben-manes.versions"
apply plugin: "kotlin"
apply plugin: "kotlin-spring"
apply plugin: "org.junit.platform.gradle.plugin"
apply plugin: "org.springframework.boot"
apply plugin: "war"
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}
sourceSets {
acceptanceTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/acceptance/kotlin')
}
resources.srcDir file('src/acceptance/resources')
}
}
configurations {
acceptanceTestCompile.extendsFrom testCompile
acceptanceTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "com.graphql-java:graphql-java-tools:3.1.3"
compile "com.graphql-java:graphql-spring-boot-starter:3.5.0"
compile "com.zaxxer:HikariCP:2.6.3"
compile("de.codecentric:spring-boot-admin-server:$springBootAdmin_version") {
exclude group: "junit", module: "junit"
}
compile("de.codecentric:spring-boot-admin-server-ui:$springBootAdmin_version") {
exclude group: "junit", module: "junit"
}
compile("de.codecentric:spring-boot-admin-starter-client:$springBootAdmin_version") {
exclude group: "junit", module: "junit"
}
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile "org.slf4j:slf4j-api:$slf4j_version"
compile "org.springframework:spring-jdbc:$spring_version"
compile "org.springframework.boot:spring-boot-starter-web:$springBoot_version"
compile "org.springframework.boot:spring-boot-starter-actuator:$springBoot_version"
compile "ru.yandex.qatools.embed:postgresql-embedded:2.2"
runtime "ch.qos.logback:logback-classic:1.2.3"
runtime "org.jolokia:jolokia-core:1.3.7"
runtime "org.liquibase:liquibase-core:3.5.3"
runtime "org.postgresql:postgresql:42.1.3"
runtime "org.slf4j:jcl-over-slf4j:$slf4j_version"
runtime "org.slf4j:jul-to-slf4j:$slf4j_version"
testCompile "com.github.sbrannen:spring-test-junit5:1.0.0.M4"
testCompile "com.nhaarman:mockito-kotlin:1.5.0"
testCompile("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") {
exclude group: "junit", module: "junit"
}
testCompile "org.junit.jupiter:junit-jupiter-api:$junitJupiter_version"
testRuntime "org.junit.jupiter:junit-jupiter-engine:$junitJupiter_version"
acceptanceTestCompile "org.springframework.boot:spring-boot-starter-test:$springBoot_version"
}
task acceptanceTest(type: Test) {
testClassesDirs = sourceSets.acceptanceTest.output.classesDirs
classpath = sourceSets.acceptanceTest.runtimeClasspath
outputs.upToDateWhen { false }
}
if (ext.runAcceptance) {
check.dependsOn acceptanceTest
}
acceptanceTest.mustRunAfter test
task wrapper(type: Wrapper) {
gradleVersion = "4.0"
}
Since Gradle 4.6 the gradle Java plugin has JUnit 5 support
So once you have configured the test source sets, the setup is as simple as follows - for my test and intTest test tasks I just need to configure this to use JUnit5:
apply plugin: 'java'
test {
useJUnitPlatform()
}
intTest {
useJUnitPlatform()
}
dependencies {
testCompile("org.junit.jupiter:junit-jupiter-api:5.1.0")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.0")
}
To refine existing answers, you need to configure each of your Test-type tasks to include useJUnitPlatform(). In your concrete example this would look like
task acceptanceTest(type: Test) {
useJUnitPlatform()
testClassesDirs = sourceSets.acceptanceTest.output.classesDirs
classpath = sourceSets.acceptanceTest.runtimeClasspath
outputs.upToDateWhen { false }
}
You can also do this centrally via
tasks.withType(Test) {
useJUnitPlatform()
}
The JUnit 5 plugin only creates one task - junitPlatformTest, and bases it on the junitPlatform extension.
If you want to run acceptance tests, or any other type of tests in another source set independently, you'll need to create your own JavaExec task, like the plugin does.
See: https://github.com/junit-team/junit5/blob/master/junit-platform-gradle-plugin/src/main/groovy/org/junit/platform/gradle/plugin/JUnitPlatformPlugin.groovy#L66
You might want to create a task like this:
task e2eTest(
type: JavaExec,
description: 'Runs the e2e tests.',
group: 'Verification'
) {
dependsOn testClasses
shouldRunAfter test
classpath = sourceSets.e2e.runtimeClasspath
main = 'org.junit.platform.console.ConsoleLauncher'
args = ['--scan-class-path',
sourceSets.e2e.output.getClassesDirs().asPath,
'--reports-dir', "${buildDir}/test-results/junit-e2e"]
}

Categories