Pipeline Task Report Generator fails - gradle

I'm trying to create a test coverage report in Azure DevOps pipelines but I get The report file "path" is invalid. File does not exist.
Before I run this failing task, I run a task to execute the tests, and I see that task runTestsWithJacoco, defined in the build.gradle to create a Jacoco report is SKIPPED.
I'm using gradle 7.0.1 and jacoco version 0.8.7.
The gradle buil for project:
buildscript {
ext.jacoco_version = "0.8.7"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.1"
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
}
}
apply plugin: PropertiesPlugin
allprojects {
repositories {
google()
mavenCentral()
}
}
The gradle.build for app
plugins {
id 'jacoco'
}
jacoco {
toolVersion = jacoco_version
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}
android {
testOptions {
unitTests.all {
useJUnitPlatform()
}
unitTests {
includeAndroidResources = true
}
}
}
task runTestsWithJacoco(
type: JacocoReport,
dependsOn: ['testDebugUnitTest'],
group: 'Reporting',
description: 'Running my tests with jacoco'
) {
def coverageSourceDirs = [
"src/main/java"
]
def fileFilter = [
'**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*'
]
def javaClasses = fileTree(
dir: buildDir,
includes: ['intermediates/javac/debug/classes/**'],
excludes: fileFilter
)
classDirectories.from(files([ javaClasses ]))
additionalSourceDirs.from(files(coverageSourceDirs))
sourceDirectories.from(files(coverageSourceDirs))
executionData.from(fileTree(dir: buildDir, includes: [
"jacoco/testDebugUnitTest.exec"
]))
reports {
xml.enabled = true
html.enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
The pipeline:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Gradle#2
name: run_unit_tests
inputs:
workingDirectory: ''
gradleWrapperFile: 'gradlew'
gradleOptions: '-Xmx3072m'
publishJUnitResults: true
testResultsFiles: 'app/build/test-results/testDebugUnitTest/TEST-*.xml'
tasks: ':app:runTestsWithJacoco'
- task: reportgenerator#4
name: generate_report
inputs:
reports: 'app/build/reports/jacoco/runTestsWithJacoco/runUnitTestsWithCoverage.xml'
targetdir: 'coverage'
sourcedirs: 'service/src/main/java'
reporttypes: 'Badges;HtmlInline_AzurePipelines;Cobertura'
Why does reportgenerator#4 fail?
I appreciate any help.

I can reproduce the same issue in reportgenerator#4 task.
The root cause of this issue can be that the publishing path you set is invalid.
You can check the build log in Gradle task and check if you can see the following log record:
To solve this issue, you can try the following sample:
- task: Gradle#2
name: run_unit_tests
inputs:
workingDirectory: ''
gradleWrapperFile: 'gradlew'
gradleOptions: '-Xmx3072m'
publishJUnitResults: true
testResultsFiles: '**/TEST-*.xml'
tasks: ':app:runTestsWithJacoco'
- task: reportgenerator#4
name: generate_report
inputs:
reports: '$(build.sourcesdirectory)/build/test-results/TEST-*.xml'
targetdir: 'coverage'
sourcedirs: 'service/src/main/java'
reporttypes: 'Badges;HtmlInline_AzurePipelines;Cobertura'
Result:

I ended up changing the build agent from Ubuntu to MacOS and that stopped the build from falling. I don't know the reason why it was failing with Ubuntu.

Related

Gradle 8.0 - 'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'

I've upgraded from Gradle 7.6 to 8.0 using (Home) brew on macOS Ventura 13.2.1 using openjdk version "19.0.2" 2023-01-17.
gradle build clean
FAILURE: Build failed with an exception.
* What went wrong:
'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
gradle build clean --scan:
Started today at 08:04:46 GMT, finished today at 08:04:51 GMT
Gradle 8.0,Gradle Enterprise plugin 3.12.3
Explore console log
1 failure
'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
Explore failure:
Failure 1 of 1'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
Exception
java.lang.NoSuchMethodError: 'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_reporting_ConfigurableReportKt.setDefaultDestinationForTask(org.gradle.api.reporting.ConfigurableReport.kt:63)
at name.remal.gradle_plugins.plugins.common.ReportsSettingsPlugin$Setup all tasks with reports$1$1.execute(ReportsSettingsPlugin.kt:24)
at name.remal.gradle_plugins.plugins.common.ReportsSettingsPlugin$Setup all tasks with reports$1$1.execute(ReportsSettingsPlugin.kt:16)
•••
at name.remal.gradle_plugins.plugins.common.ReportsSettingsPlugin$Setup all tasks with reports$1.execute(ReportsSettingsPlugin.kt:22)
at name.remal.gradle_plugins.plugins.common.ReportsSettingsPlugin$Setup all tasks with reports$1.execute(ReportsSettingsPlugin.kt:16)
•••
at name.remal.gradle_plugins.plugins.common.ReportsSettingsPlugin.Setup all tasks with reports(ReportsSettingsPlugin.kt:20)
•••
at name.remal.gradle_plugins.dsl.extensions.Java_lang_reflect_MethodKt.invokeForInstance(java.lang.reflect.Method.kt:21)
at name.remal.gradle_plugins.dsl.reflective_project_plugin.action_param_injector.ExtensionsKt.invokeForProject(extensions.kt:15)
at name.remal.gradle_plugins.dsl.reflective_project_plugin.action_param_injector.ExtensionsKt.invoke(extensions.kt:23)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1$7.invoke(BaseReflectiveProjectPlugin.kt:103)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1$7.invoke(BaseReflectiveProjectPlugin.kt:19)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_plugins_PluginManagerKt.withPluginIds(org.gradle.api.plugins.PluginManager.kt:67)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_ProjectKt.withPluginIds(org.gradle.api.Project.kt:193)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1.invoke(BaseReflectiveProjectPlugin.kt:88)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1.invoke(BaseReflectiveProjectPlugin.kt:19)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_plugins_PluginManagerKt.withPluginIds(org.gradle.api.plugins.PluginManager.kt:67)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_ProjectKt.withPluginIds(org.gradle.api.Project.kt:193)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin.doActions(BaseReflectiveProjectPlugin.kt:67)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin.applyImpl(BaseReflectiveProjectPlugin.kt:43)
at name.remal.gradle_plugins.dsl.BaseProjectPlugin.apply(BaseProjectPlugin.kt:57)
at name.remal.gradle_plugins.dsl.BaseProjectPlugin.apply(BaseProjectPlugin.kt:23)
•••
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_ProjectKt.applyPlugin(org.gradle.api.Project.kt:195)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1.invoke(BaseReflectiveProjectPlugin.kt:69)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin$doActions$1.invoke(BaseReflectiveProjectPlugin.kt:19)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_plugins_PluginManagerKt.withPluginIds(org.gradle.api.plugins.PluginManager.kt:67)
at name.remal.gradle_plugins.dsl.extensions.Org_gradle_api_ProjectKt.withPluginIds(org.gradle.api.Project.kt:193)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin.doActions(BaseReflectiveProjectPlugin.kt:67)
at name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin.applyImpl(BaseReflectiveProjectPlugin.kt:43)
at name.remal.gradle_plugins.dsl.BaseProjectPlugin.apply(BaseProjectPlugin.kt:57)
at name.remal.gradle_plugins.dsl.BaseProjectPlugin.apply(BaseProjectPlugin.kt:23)
•••
Moved back to Gradle 7.6:
/gradlew build clean --warning-mode=all
> Configure project :
The Report.destination property has been deprecated. This is scheduled to be removed in Gradle 8.0. Please use the outputLocation property instead. See https://docs.gradle.org/7.6/dsl/org.gradle.api.reporting.Report.html#org.gradle.api.reporting.Report:destination for more details.
The Report.enabled property has been deprecated. This is scheduled to be removed in Gradle 8.0. Please use the required property instead. See https://docs.gradle.org/7.6/dsl/org.gradle.api.reporting.Report.html#org.gradle.api.reporting.Report:enabled for more details.
>>>>> 1 deleteFiles
>>>>> 2 NOTiFYmotoWAR
The AbstractArchiveTask.archiveName property has been deprecated. This is scheduled to be removed in Gradle 8.0. Please use the archiveFileName property instead. See https://docs.gradle.org/7.6/dsl/org.gradle.api.tasks.bundling.AbstractArchiveTask.html#org.gradle.api.tasks.bundling.AbstractArchiveTask:archiveName for more details.
at build_6fdw9omce69ijjc1fgog2e4q0$_run_closure13.doCall(/Users/NOTiFY/IdeaProjects/NOTiFYmoto/build.gradle:265)
(Run with --stacktrace to get the full stack trace of this deprecation warning.)
>>>>> 3 NOTiFYmotoJAR
>>>>> 4 copyNOTiFYmotoWAR
>>>>> 5 copyNOTiFYmotoJAR
>>>>> 6 NOTiFYmotoEAR
My Gradle:
plugins {
id("war")
id("ear")
id("idea")
id("java-library")
id("org.jetbrains.kotlin.jvm") version "1.8.10"
id("checkstyle")
id("pmd")
id("com.github.spotbugs") version "5.0.13"
id("org.sonarqube") version "3.5.0.2730"
id("name.remal.sonarlint") version "1.5.0"
id("org.wildfly.build.provision") version "0.0.11"
}
configurations.all {
resolutionStrategy {
//force 'xml-apis:xml-apis:1.0.b2'
force 'xml-apis:xml-apis:2.0.2'
}
}
compileJava {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
repositories {
mavenLocal()
mavenCentral()
google()
maven {
name "jboss-nexus"
url "http://repository.jboss.org/nexus/content/groups/public/"
url "https://repository.jboss.org/nexus/content/groups/public-jboss"
url "https://repository.jboss.org/nexus/content/repositories"
url "https://repository.jboss.org/nexus/content/repositories/thirdparty-releases"
url "https://repository.primefaces.org"
}
//jcenter()
gradlePluginPortal()
mavenCentral()
flatDir {
dirs "lib"
}
}
dependencies {
compileOnly("jakarta.platform:jakarta.jakartaee-api:10.0.0")
implementation("jakarta.platform:jakarta.jakartaee-web-api:10.0.0")
// JUnit (Jupiter) 5.9.0)
testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.2')
testImplementation('org.junit.jupiter:junit-jupiter-engine:5.9.2')
testImplementation('org.junit.vintage:junit-vintage-engine:5.9.2')
testImplementation("org.testng:testng:7.7.0")
implementation("org.apache.maven.surefire:surefire-testng:2.22.2")
implementation("org.slf4j:slf4j-api:2.0.5")
implementation("org.slf4j:slf4j-simple:2.0.5")
implementation('com.puppycrawl.tools:checkstyle:10.7.0')
implementation("dev.morphia.morphia:morphia-core:2.3.0")
// Omnifaces 4.0.1 - November 2022
implementation("org.omnifaces:omnifaces:4.0.1")
implementation("org.primefaces:primefaces-12.0.3-jakarta")
implementation("org.primefaces.themes:bootstrap:1.0.10")
// BootsFaces
implementation("net.bootsfaces:bootsfaces:1.5.0")
implementation("org.mongodb:mongodb-driver-core:4.8.2")
implementation("org.mongodb:mongodb-driver-sync:4.8.2")
implementation("org.mongodb:bson:4.8.2")
implementation('io.github.classgraph:classgraph:4.8.154')
implementation('net.bytebuddy:byte-buddy:1.12.21')
implementation('com.google.code.gson:gson:2.10.1')
// Kotlin - 2022-12-28
implementation('org.jetbrains.kotlin:kotlin-stdlib:1.8.10')
implementation("org.jsoup:jsoup:1.15.3")
providedCompile("org.eclipse.persistence:javax.persistence:2.2.1")
providedCompile("javax.inject:javax.inject:1")
providedCompile("javax.faces:javax.faces-api:2.3")
providedCompile("jakarta.enterprise:jakarta.enterprise.cdi-api:4.0.1")
providedCompile("org.jboss.resteasy:resteasy-jaxrs:3.15.3.Final")
providedCompile('com.google.code.gson:gson:2.10.1')
providedCompile("javax.ws.rs:javax.ws.rs-api:2.1.1")
providedCompile("org.slf4j:slf4j-api:2.0.5")
providedCompile("org.slf4j:slf4j-simple:2.0.5")
spotbugsPlugins("com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0")
}
checkstyleMain {
source = ["src/main/java"]
}
checkstyle {
toolVersion "10.7.0"
configFile = file("config/checkstyle/checkstyle.xml")
}
spotbugs {
ignoreFailures = true
toolVersion = '4.7.3'
reportsDir = file("reports/spotbugs")
effort = "max"
reportLevel = "high"
// ignoreFailures = false
showProgress = true
// showStackTraces = false
// effort = "default"
// reportLevel = "default"
// visitors = [ "FindSqlInjection", "SwitchFallthrough" tVisitors = [ "FindNonShortCircuit" ]
// reportsDir = filef("$buildDir/ƒprime")
// includeFilter = file("include.xml")
// excludeFilter = file("exclude.xml")
// onlyAnalyze = [ "com.foobar.MyClass", "com.foobar.mypkg.*" ]
// maxHeapSize = "1g"
// extraArgs = [ "-nested:false" ]
// jvmArgs = [ "-Duser.language=ja" ]
}
pmd {
ignoreFailures = true
reportsDir = file("reports/pmd")
ruleSets = [
"java-basic",
"java-braces",
"java-clone",
"java-codesize",
"java-comments",
"java-controversial",
"java-coupling",
"java-design",
"java-empty",
"java-finalizers",
"java-imports",
"java-optimizations",
"java-strictexception",
"java-strings",
"java-typeresolution",
"java-unnecessary",
"java-unusedcode"
]
}
// SonarLint & SonarQube
sonarlint {
ignoreFailures = true
// excludes {
// message 'java:S1214'
// message 'kotlin:S100'
// message 'xml:S125'
// }
// includes {
// message 'java:S4266' // Enable java:S4266 which is disabled by default
// }
// ruleParameter('java:S119', 'format', '^[A-Z][a-zA-Z0-9]*$') // Allow upper camel-case for type parameter names
}
tasks.withType(Pmd) {
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
reports {
html.destination rootProject.file("reports/checkstyle/checkstyle.html")
}
}
task deleteFiles(type: Delete) {
project.logger.lifecycle(">>>>> 1 deleteFiles")
delete fileTree("./build/libs") {
include "**/NOTiFYmoto*.?ar"
}
delete fileTree("./src/main/application") {
include "**/NOTiFYmoto*.war"
include "**/NOTiFYmoto*.jar"
include "**/NOTiFYmoto*.ear"
}
}
task NOTiFYmotoWAR(type: War) {
project.logger.lifecycle(">>>>> 2 NOTiFYmotoWAR")
dependsOn deleteFiles
archiveName "NOTiFYmotoWAR.war"
//archiveFileName "NOTiFYmotoWAR.war"
//webInf {
// from "WEB-INF"
//}
rootSpec.exclude("**/dto/*")
rootSpec.exclude("**/ean/*")
rootSpec.exclude("**/ejb/*")
rootSpec.exclude("**/entity/*")
rootSpec.exclude("**/filter/*")
rootSpec.exclude("**/gson/*")
rootSpec.exclude("**/morphia-*.jar")
rootSpec.exclude("**/mongo*.jar")
rootSpec.exclude("**/bson*.jar")
rootSpec.exclude("**/surefire*.jar")
rootSpec.exclude("**/controller*/*")
// Exclude push PushEvent.class
rootSpec.exclude("**/push/PushEvent.class")
//rootSpec.exclude("**/layout/img/OmniFaces-icon-*")
rootSpec.exclude("**/webservices/*")
rootSpec.exclude("**/checkstyle*.jar")
rootSpec.exclude("**/classgraph*.jar")
rootSpec.exclude("**/kotlin*.jar")
rootSpec.exclude("**/NOTiFYmoto*.jar")
rootSpec.exclude("**/NOTiFYmoto*.war")
}
task NOTiFYmotoJAR(type: Jar) {
project.logger.lifecycle(">>>>> 3 NOTiFYmotoJAR")
dependsOn NOTiFYmotoWAR
archiveName "NOTiFYmotoJAR.jar"
// archiveFileName "NOTiFYmotoJAR.jar"
from("./src/main/java") {
include "META-INF/**"
}
// Exclude
rootSpec.exclude("**/jsf/SliderViewBean.class")
rootSpec.exclude("**/push/PushBean.class")
from("./build/classes/java/main") {
include "*/**"
}
// Kotlin
from("./build/classes/kotlin/main") {
include "*/**"
}
}
task copyNOTiFYmotoWAR(type: Copy) {
project.logger.lifecycle(">>>>> 4 copyNOTiFYmotoWAR")
dependsOn NOTiFYmotoJAR
from file("./build/libs/NOTiFYmotoWAR.war")
into file("./src/main/application")
}
task copyNOTiFYmotoJAR(type: Copy) {
project.logger.lifecycle(">>>>> 5 copyNOTiFYmotoJAR")
dependsOn copyNOTiFYmotoWAR
from file("./build/libs/NOTiFYmotoJAR.jar")
into file("./src/main/application")
}
task NOTiFYmotoEAR(type: Ear) {
project.logger.lifecycle(">>>>> 6 NOTiFYmotoEAR")
apply plugin: "ear"
//compileOnly("org.omnifaces:omnifaces:4.0.1")
dependsOn copyNOTiFYmotoJAR
archiveName "NOTiFYmoto.ear"
// archiveFileName "NOTiFYmoto.ear"
manifest {
from("./src/main/resources/META-INF/MANIFEST.MF")
}
exclude "**/*.class"
exclude "**/asm-Java.jar"
exclude "**/jboss-deployment-structure.xml"
// exclude("**/beans.xml")
dependencies {
earlib group: "com.google.code.gson", name: "gson", version: "2.10", ext: "jar"
earlib group: "org.apache.httpcomponents", name: "httpclient", version: "4.5.13", ext: "jar"
earlib group: "org.apache.httpcomponents", name: "httpcore", version: "4.4.14", ext: "jar"
earlib group: "org.jetbrains.kotlin", name: "kotlin-stdlib", version: "1.8.10", ext: "jar"
earlib group: "dev.morphia.morphia", name: "morphia-core", version: "2.3.0", ext: "jar"
earlib group: "org.mongodb", name: "mongodb-driver-core", version: "4.8.2", ext: "jar"
earlib group: "org.mongodb", name: "mongodb-driver-sync", version: "4.8.2", ext: "jar"
earlib group: "org.mongodb", name: "bson", version: "4.8.2", ext: "jar"
earlib group: "net.bytebuddy", name: "byte-buddy", version: "1.12.17", ext: "jar"
earlib group: "io.github.classgraph", name: "classgraph", version: "4.8.153"
spotbugsPlugins("com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0")
}
}
Any suggestions? TIA
The following is an example of migrating the deprecated report properties on build.gradle files from Gradle 7.x.x. to 8.0.0:
Gradle 7.x.x
jacoco {
toolVersion = "0.8.6"
reportsDirectory = file("$buildDir/customJacocoReportDir")
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled true
html.destination file("${buildDir}/reports/html/jacoco")
}
}
Gradle 8.0.0
jacoco {
toolVersion = "0.8.8"
reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
jacocoTestReport {
reports {
xml.required = false
csv.required = true
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}
So in regards to the build.gradle in the question, it will migrate from:
Current
tasks.withType(Pmd) {
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
reports {
html.destination rootProject.file("reports/checkstyle/checkstyle.html")
}
}
New
tasks.withType(Pmd) {
reports {
xml.required = true
html.required = true
}
}
tasks.withType(Checkstyle) {
reports {
html.outputLocation = rootProject.file('reports/checkstyle/checkstyle.html')
}
}
Deleted:
rm -rf .m2
rm -rf $HOME/.gradle/caches/
After refactoring some code. I ran (Home) brew & deleting Gradle 7.6 & install 8.0. Gradle was running 'again'. No apparent reason.
Just noticed that Gradle 8.0 was upgraded to 8.0.1.
gradle wrapper --gradle-version 8.0.1
Still errors:
/gradlew build clean
Downloading https://services.gradle.org/distributions/gradle-8.0.1-bin.zip
...........10%............20%............30%............40%............50%............60%...........70%............80%............90%............100%
Welcome to Gradle 8.0.1!
Here are the highlights of this release:
- Improvements to the Kotlin DSL
- Fine-grained parallelism from the first build with configuration cache
- Configurable Gradle user home cache cleanup
For more details see https://docs.gradle.org/8.0.1/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
> Configure project :
POM relocation to an other version number is not fully supported in Gradle : xml-apis:xml-apis:2.0.2 relocated to xml-apis:xml-apis:1.0.b2.
Please update your dependency to directly use the correct version 'xml-apis:xml-apis:1.0.b2'.
Resolution will only pick dependencies of the relocated element. Artifacts and other metadata will be ignored.
FAILURE: Build failed with an exception.
* What went wrong:
'java.io.File org.gradle.api.reporting.ConfigurableReport.getDestination()'
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1m 6s
To run Gradle (8.0.1) have to change "gradle-wrapper.properties" to:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
# distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Gitlab CI failure with JHipster

I can build my JHipster gateway with gradle from the development machine, but when I give it to the Gitlab CI I get this error at the 'gradle-package' step:
92 $ ./gradlew bootJar -Pprod -x check --no-daemon
93 To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/6.4.1/userguide/gradle_daemon.html.
94 Daemon will be stopped at the end of the build stopping after processing
95 > Task :bootBuildInfo
96 > Task :nodeSetup SKIPPED
97 > Task :npmSetup SKIPPED
98 > Task :npmInstall UP-TO-DATE
99 > Task :webpack FAILED
100 FAILURE: Build failed with an exception.
101 * What went wrong:
102 Execution failed for task ':webpack'.
103 > A problem occurred starting process 'command 'npm''
This is the .gitlab-ci.yml
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- .gradle/
stages:
- check
- build
- test
- analyze
- package
- release
- deploy
before_script:
- export NG_CLI_ANALYTICS="false"
- export GRADLE_USER_HOME=`pwd`/.gradle
- ./gradlew npm_install -PnodeInstall --no-daemon
nohttp:
stage: check
script:
- ./gradlew checkstyleNohttp --no-daemon
gradle-compile:
stage: build
script:
- ./gradlew compileJava -x check -PnodeInstall --no-daemon
artifacts:
paths:
- build/classes/
- build/generated/
expire_in: 1 day
gradle-test:
stage: test
script:
- ./gradlew test -PnodeInstall --no-daemon
artifacts:
reports:
junit: build/test-results/test/TEST-*.xml
paths:
- build/test-results/
- build/jacoco/
expire_in: 1 day
gradle-integration-test:
stage: test
script:
- ./gradlew integrationTest -PnodeInstall --no-daemon
artifacts:
reports:
junit: build/test-results/integrationTest/TEST-*.xml
paths:
- build/test-results/
- build/jacoco/
expire_in: 1 day
frontend-test:
stage: test
script:
- ./gradlew npm_run_test -PnodeInstall --no-daemon
artifacts:
reports:
junit: build/test-results/TESTS-results-jest.xml
paths:
- build/test-results/
- build/jacoco/
expire_in: 1 day
gradle-package:
stage: package
script:
- ./gradlew bootJar -Pprod -x check --no-daemon
artifacts:
paths:
- build/libs/*.jar
- build/classes
expire_in: 1 day
# Uncomment the following line to use gitlabs container registry. You need to adapt the REGISTRY_URL in case you are not using gitlab.com
docker-push:
stage: release
variables:
REGISTRY_URL: 10.1.10.58
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHA
dependencies:
- gradle-package
script:
- ./gradlew jib -Pprod -Djib.allowInsecureRegistries=true -Djib.to.image=$IMAGE_TAG -Djib.to.auth.username="gitlab-ci-token" -Djib.to.auth.password=$CI_BUILD_TOKEN
build.gradle
buildscript {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
//jhipster-needle-gradle-buildscript-dependency - JHipster will add additional gradle build script plugins here
}
}
plugins {
id "java"
id "maven-publish"
id "idea"
id "jacoco"
id "org.springframework.boot"
id "com.google.cloud.tools.jib"
id "com.gorylenko.gradle-git-properties"
id "com.github.node-gradle.node"
id "net.ltgt.apt-eclipse"
id "net.ltgt.apt-idea"
id "net.ltgt.apt"
id "org.liquibase.gradle"
id "org.sonarqube"
id "io.spring.nohttp"
//jhipster-needle-gradle-plugins - JHipster will add additional gradle plugins here
}
group = "com.rps.png"
version = "0.0.1-SNAPSHOT"
description = ""
sourceCompatibility=1.8
targetCompatibility=1.8
assert System.properties["java.specification.version"] == "1.8" || "11" || "12" || "13" || "14"
apply from: "gradle/docker.gradle"
apply from: "gradle/sonar.gradle"
//jhipster-needle-gradle-apply-from - JHipster will add additional gradle scripts to be applied here
if (project.hasProperty("prod") || project.hasProperty("gae")) {
apply from: "gradle/profile_prod.gradle"
} else {
apply from: "gradle/profile_dev.gradle"
}
if (project.hasProperty("war")) {
apply from: "gradle/war.gradle"
}
if (project.hasProperty("gae")) {
apply plugin: 'maven'
apply plugin: 'org.springframework.boot.experimental.thin-launcher'
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom "io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}"
}
}
appengineStage.dependsOn thinResolve
}
if (project.hasProperty("zipkin")) {
apply from: "gradle/zipkin.gradle"
}
idea {
module {
excludeDirs += files("node_modules")
}
}
eclipse {
sourceSets {
main {
java {
srcDirs += ["build/generated/sources/annotationProcessor/java/main"]
}
}
}
}
defaultTasks "bootRun"
springBoot {
mainClassName = "com.rps.png.GatewayuApp"
}
test {
useJUnitPlatform()
exclude "**/*IT*", "**/*IntTest*"
testLogging {
events 'FAILED', 'SKIPPED'
}
// uncomment if the tests reports are not generated
// see https://github.com/jhipster/generator-jhipster/pull/2771 and https://github.com/jhipster/generator-jhipster/pull/4484
// ignoreFailures true
reports.html.enabled = false
}
task integrationTest(type: Test) {
useJUnitPlatform()
description = "Execute integration tests."
group = "verification"
include "**/*IT*", "**/*IntTest*"
testLogging {
events 'FAILED', 'SKIPPED'
}
if (project.hasProperty('testcontainers')) {
environment 'spring.profiles.active', 'testcontainers'
}
// uncomment if the tests reports are not generated
// see https://github.com/jhipster/generator-jhipster/pull/2771 and https://github.com/jhipster/generator-jhipster/pull/4484
// ignoreFailures true
reports.html.enabled = false
}
check.dependsOn integrationTest
task testReport(type: TestReport) {
destinationDir = file("$buildDir/reports/tests")
reportOn test
}
task integrationTestReport(type: TestReport) {
destinationDir = file("$buildDir/reports/tests")
reportOn integrationTest
}
if (!project.hasProperty("runList")) {
project.ext.runList = "main"
}
project.ext.diffChangelogFile = "src/main/resources/config/liquibase/changelog/" + new Date().format("yyyyMMddHHmmss") + "_changelog.xml"
liquibase {
activities {
main {
driver "org.h2.Driver"
url "jdbc:h2:file:./build/h2db/db/gatewayu"
username "gatewayu"
password ""
changeLogFile "src/main/resources/config/liquibase/master.xml"
defaultSchemaName ""
logLevel "debug"
classpath "src/main/resources/"
}
diffLog {
driver "org.h2.Driver"
url "jdbc:h2:file:./build/h2db/db/gatewayu"
username "gatewayu"
password ""
changeLogFile project.ext.diffChangelogFile
referenceUrl "hibernate:spring:com.rps.png.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"
defaultSchemaName ""
logLevel "debug"
classpath "$buildDir/classes/java/main"
}
}
runList = project.ext.runList
}
gitProperties {
failOnNoGitDirectory = false
keys = ["git.branch", "git.commit.id.abbrev", "git.commit.id.describe"]
}
checkstyle {
toolVersion '${checkstyle_version}'
configFile file("checkstyle.xml")
checkstyleTest.enabled = false
}
nohttp {
source.include "build.gradle", "README.md"
}
configurations {
providedRuntime
implementation.exclude module: "spring-boot-starter-tomcat"
all {
resolutionStrategy {
// Inherited version from Spring Boot can't be used because of regressions:
// To be removed as soon as spring-boot use the same version
force 'org.liquibase:liquibase-core:3.9.0'
}
}
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
//jhipster-needle-gradle-repositories - JHipster will add additional repositories
}
dependencies {
// import JHipster dependencies BOM
if (!project.hasProperty("gae")) {
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
}
// Use ", version: jhipster_dependencies_version, changing: true" if you want
// to use a SNAPSHOT release instead of a stable release
implementation group: "io.github.jhipster", name: "jhipster-framework"
implementation "javax.annotation:javax.annotation-api"
implementation "org.springframework.boot:spring-boot-starter-cache"
implementation "io.dropwizard.metrics:metrics-core"
implementation "io.micrometer:micrometer-registry-prometheus"
implementation "net.logstash.logback:logstash-logback-encoder"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-hppc"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
implementation "com.fasterxml.jackson.module:jackson-module-jaxb-annotations"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-hibernate5"
implementation "com.fasterxml.jackson.core:jackson-annotations"
implementation "com.fasterxml.jackson.core:jackson-databind"
implementation "com.fasterxml.jackson.module:jackson-module-afterburner"
implementation "org.apache.httpcomponents:httpclient"
implementation "javax.cache:cache-api"
implementation "org.hibernate:hibernate-core"
implementation "com.zaxxer:HikariCP"
implementation "commons-codec:commons-codec"
implementation "org.apache.commons:commons-lang3"
implementation "commons-io:commons-io"
implementation "javax.transaction:javax.transaction-api"
implementation "org.ehcache:ehcache"
implementation "org.hibernate:hibernate-jcache"
implementation "org.hibernate:hibernate-entitymanager"
implementation "org.hibernate.validator:hibernate-validator"
implementation "org.liquibase:liquibase-core"
liquibaseRuntime "org.liquibase:liquibase-core"
liquibaseRuntime "org.liquibase.ext:liquibase-hibernate5:${liquibase_hibernate5_version}"
liquibaseRuntime sourceSets.main.compileClasspath
implementation "org.springframework.boot:spring-boot-loader-tools"
implementation "org.springframework.boot:spring-boot-starter-mail"
implementation "org.springframework.boot:spring-boot-starter-logging"
implementation "org.springframework.boot:spring-boot-starter-actuator"
implementation "org.springframework.boot:spring-boot-starter-aop"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
testImplementation "org.testcontainers:mysql"
implementation "org.springframework.boot:spring-boot-starter-security"
implementation ("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
implementation "org.springframework.boot:spring-boot-starter-undertow"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf"
implementation "org.zalando:problem-spring-web"
implementation "org.springframework.cloud:spring-cloud-starter-netflix-zuul"
implementation "com.github.vladimir-bukhtoyarov:bucket4j-core"
implementation "com.github.vladimir-bukhtoyarov:bucket4j-jcache"
implementation "org.springframework.cloud:spring-cloud-starter"
implementation "org.springframework.cloud:spring-cloud-starter-netflix-ribbon"
implementation "org.springframework.cloud:spring-cloud-starter-netflix-hystrix"
implementation "org.springframework.retry:spring-retry"
implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client"
implementation "org.springframework.cloud:spring-cloud-starter-config"
implementation "org.springframework.cloud:spring-cloud-starter-security"
implementation "org.springframework.cloud:spring-cloud-starter-openfeign"
implementation "org.springframework.boot:spring-boot-starter-cloud-connectors"
implementation "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-data"
implementation "org.springframework.security:spring-security-web"
implementation "org.springframework.security.oauth:spring-security-oauth2"
implementation "org.springframework.security:spring-security-jwt"
implementation "org.glassfish.jaxb:jaxb-runtime:${jaxb_runtime_version}"
implementation ("io.springfox:springfox-swagger2") {
exclude module: "mapstruct"
}
implementation "io.springfox:springfox-bean-validators"
implementation "mysql:mysql-connector-java"
liquibaseRuntime "mysql:mysql-connector-java"
implementation "org.mapstruct:mapstruct:${mapstruct_version}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstruct_version}"
annotationProcessor "org.hibernate:hibernate-jpamodelgen:${hibernate_version}"
annotationProcessor "org.glassfish.jaxb:jaxb-runtime:${jaxb_runtime_version}"
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:${spring_boot_version}"
testImplementation ("org.springframework.boot:spring-boot-starter-test") {
exclude group: "org.junit.vintage", module: "junit-vintage-engine"
}
testImplementation "org.springframework.security:spring-security-test"
testImplementation "org.springframework.boot:spring-boot-test"
testImplementation "com.tngtech.archunit:archunit-junit5-api:${archunit_junit5_version}"
testRuntimeOnly "com.tngtech.archunit:archunit-junit5-engine:${archunit_junit5_version}"
testImplementation "com.h2database:h2"
liquibaseRuntime "com.h2database:h2"
//jhipster-needle-gradle-dependency - JHipster will add additional dependencies here
}
if (project.hasProperty("gae")) {
task createPom {
def basePath = 'build/resources/main/META-INF/maven'
doLast {
pom {
withXml(dependencyManagement.pomConfigurer)
}.writeTo("${basePath}/${project.group}/${project.name}/pom.xml")
}
}
bootJar.dependsOn = [createPom]
}
task cleanResources(type: Delete) {
delete "build/resources"
}
wrapper {
gradleVersion = "6.4.1"
}
if (project.hasProperty("nodeInstall")) {
node {
version = "${node_version}"
npmVersion = "${npm_version}"
yarnVersion = "${yarn_version}"
download = true
}
}
compileJava.dependsOn processResources
processResources.dependsOn bootBuildInfo
This is a JHipster gateway 6.9 with only minor changes from the default. In particular, I didnt' touch the 'gradle-package' which is failing on the Gitlab Runner.
What's the [Docker] image you run your job on? I don't see any image: specifications in your .gitlab-ci.yml. Make sure it has npm installed or make sure that your Gradle scripts contains instructions or tasks for installing it. You should probably set nodeInstall property before running the build:
if (project.hasProperty("nodeInstall")) {
node {
version = "${node_version}"
npmVersion = "${npm_version}"
yarnVersion = "${yarn_version}"
download = true
}
}

How to enable Allure history using Gradle and Junit5?

I know I could copy the history directory from allure-reports to a generated allure-results, and then do allure generate to get the history to show up, but I am looking for a way to achieve this with the built-in functionality in allure-gradle.
Currently, I run ./gradlew clean test, then ./gradlew allureReport, and this gives me a fresh html report with no history or reruns. I have noticed that the test task deletes the entire allure-reports directory and then re-makes and re-populates it.
Here is my build.gradle:
buildscript {
repositories {
mavenLocal()
jcenter()
}
}
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'java'
id 'eclipse'
// Allure reporter
id 'io.qameta.allure' version '2.8.1'
}
repositories {
mavenCentral()
jcenter()
}
def allureVersion = "2.13.1"
allure {
autoconfigure = true
version = allureVersion
useJUnit5 {
version = '2.0-BETA10'
}
downloadLink = "https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.13.1/allure-commandline-2.13.1.zip"
}
test {
useJUnitPlatform() {
includeEngines 'junit-jupiter'
}
ignoreFailures = true
}
dependencies {
compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0'
compile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.6.0'
compile group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.6.0'
// Needed as a workaround for JUnit 5 not failing tests that stopped due to an error message. The fix is in eclipse 4.10
compile group: 'org.junit.vintage', name: 'junit-vintage-engine', version: '5.6.0'
compile group: 'io.qameta.allure', name: 'allure-junit5', version: '2.13.1'
compile group: 'io.qameta.allure', name: 'allure-java-commons', version: '2.13.1'
// https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
I have also tried specifying the results and reports directories to be outside of the build directory, like this:
allure {
autoconfigure = true
version = allureVersion
resultsDir = file('../../allure-results')
reportDir = file('../../allure-report')
...
}
This allows the allure-results folder to keep the previous report, which show up as retries (not quite right), but history still doesn't work.
I have solved this problem by adding at the running test script these lines( I have some tests scuites)
call gradlew test -PsuiteFile=YOUR_TEST_SUITE.xml
mkdir allure-results\history
xcopy build\allure-results\* allure-results\history
allure serve allure-results\history
So I have added folder allure-results\history to keep all results

problem with java and travis-ci, codacy coverage and gradle

I have tried in several places how to configure the coverage of Codacy in travis-ci using gradle.
What I find is how to configure Gradle, without travis-CI. I wanted to do something automatic.
Could anyone help?
ADD:
my build.gradle
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id "org.sonarqube" version "2.6"
id 'com.gradle.build-scan' version '1.16'
}
configurations { codacy }
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.rjdesenvolvimento'
version = '0.0.1'
sourceCompatibility = 1.11
repositories {
mavenCentral()
}
tasks.withType(Test) { enabled = false }
dependencies {
testImplementation 'junit:junit:4.12'
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final'
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-security')
implementation('org.springframework.boot:spring-boot-starter-web')
runtimeOnly('org.springframework.boot:spring-boot-devtools')
runtimeOnly('org.postgresql:postgresql')
annotationProcessor("org.projectlombok:lombok:1.18.2")
compileOnly('org.projectlombok:lombok')
compileOnly('org.sonarsource.sonarqube:sonar-plugin-api:7.3')
compileOnly('org.jacoco:org.jacoco.core:0.8.2')
compileOnly('org.jacoco:org.jacoco.agent:0.8.2')
compileOnly('com.codacy:codacy-coverage-reporter:5.0.310')
testCompile group: 'com.h2database', name: 'h2', version: '1.4.197'
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.security:spring-security-test')
compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.4.0-b180830.0359'
codacy 'com.github.codacy:codacy-coverage-reporter:-SNAPSHOT'
}
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) {
main = "com.codacy.CodacyCoverageReporter"
classpath = configurations.codacy
args = [
"report",
"-l",
"Java",
"-r",
"${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
]
}
jacocoTestReport{
additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
reports {
xml.enabled false
csv.enabled false
html.destination "${buildDir}/reports/jacoco/html"
}
executionData = files('build/jacoco/test.exec')
}
test {
finalizedBy jacocoTestReport
}
and the travis.yml
env:
- CODACY_PROJECT_TOKEN=c8f9b1f6aab444018dd4e3...
language: java
install: true
jdk:
- oraclejdk11
before_install:
- chmod +x gradlew
- sudo apt-get install jq
- wget -O ~/codacy-coverage-reporter-assembly-latest.jar $(curl https://api.github.com/repos/codacy/codacy-coverage-reporter/releases/latest | jq -r '.assets[0].browser_download_url')
dist: trusty
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
addons:
sonarcloud:
organization: "rjdesenvolvimento-github"
token:
secure: 5150fa5cbf1f86006a140e0b8a96e...
script:
- ./gradlew build --scan -s sonarqube -Dsonar.projectKey=rjdesenvolvimento_apipessoas -Dsonar.organization=rjdesenvolvimento-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=5150fa5cbf1f86006a140e0b8a96e...
after_success:
- bash <(curl -s https://codecov.io/bash)>
java -jar ~/codacy-coverage-reporter-assembly-latest.jar report -l Java -r build/reports/jacoco/test/jacocoTestReport.xml
And the travis-ci
> Task :compileJava
> Task :processResources
> Task :classes
> Task :bootJar
> Task :jar SKIPPED
> Task :assemble
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test SKIPPED
> Task :jacocoTestReport SKIPPED
> Task :check UP-TO-DATE
> Task :build
> Task :sonarqube
$ java -jar ~/codacy-coverage-reporter-assembly-latest.jar report -l Java -r build/reports/jacoco/test/jacocoTestReport.xml
10/24 23:51:49 INFO c.c.rules.ConfigurationRules:101 - Using API base URL: https://api.codacy.com
10/24 23:51:49 ERROR c.c.CodacyCoverageReporter$:28 - File /home/travis/build/rjdesenvolvimento/apipessoas/build/reports/jacoco/test/jacocoTestReport.xml does not exist.
And so far no coverage
Have you tried to create a Gradle task as explained here? https://github.com/codacy/codacy-coverage-reporter/blob/master/README.md#gradle-task
The solution seems to be present in the documentation.
First you need a gradle task. There seem to be 2 examples at: https://github.com/codacy/codacy-coverage-reporter/blob/master/README.md#gradle-task
Then you should update your travis-ci steps to automatically send the coverage report on each run. Something along with https://github.com/codacy/codacy-coverage-reporter/blob/master/README.md#travis-ci, but using the gradle task you just defined

Gradle powermock codecoverage missed

How to configure gradle to produce code coverage for sonar when i'm using powermock in my tests? I found that jacoco don't support that. Is there any other codecoverage plugin to work with powermock?
Jacoco Offline Instrumentation is the solution for this.
see my gradle build file
Build and run tests:
Linux:
\$ ./gradlew
Windows:
\$ gradlew
------------------------------------------
"""
apply plugin: 'java'
apply plugin: 'org.sonarqube'
apply plugin: 'jacoco'
// Project group and version
group 'com.abcd.jacocoTest'
version '1.0.0'
// JDK version source compatibility
sourceCompatibility = 1.8
// JDK version target compatibility
targetCompatibility = 1.8
configurations {
jacocoAnt
jacocoRuntime
}
task wrapper(type: Wrapper) {
gradleVersion = "4.5.1"
}
defaultTasks 'clean', 'test'
buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2"
}
}
repositories {
mavenCentral()
}
dependencies {
jacocoAnt group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.1'
jacocoAgent group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.8.9'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.4'
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.4'
testCompile group: 'org.powermock', name: 'powermock-api-easymock', version: '1.7.4'
}
test {
testLogging {
afterSuite { desc, result ->
if (!desc.parent) { // will match the outermost suite
println "Unit Tests: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
}
}
}
jacoco {
append = "false"
destinationFile = file("$buildDir/reports/jacoco/jacoco-sonar/jacoco-coverage.exec")
}
}
jacoco {
toolVersion = "0.8.0"
}
jacocoTestReport {
reports {
html.destination file("${buildDir}/reports/jacoco/jacocoHtml")
}
}
sonarqube {
properties {
property "sonar.projectName", 'JacocoTest'
property "sonar.host.url", "http://localhost:9000"
property "sonar.java.binaries", "${buildDir}/classes"
property "sonar.java.libraries", "**/*.jar"
property "sonar.dynamicAnalysis", "reuseReports"
property "sonar.jacoco.reportPaths", "${buildDir}/reports/jacoco/jacoco-sonar/jacoco-coverage.exec"
}
}
task instrument(dependsOn: ['classes']) {
ext.outputDir = buildDir.path + '/reports/classes-instrumented'
doLast {
ant.taskdef(name: 'instrument',
classname: 'org.jacoco.ant.InstrumentTask',
classpath: configurations.jacocoAnt.asPath)
ant.instrument(destdir: outputDir) {
fileset(dir: sourceSets.main.output.classesDir)
}
}
}
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(instrument)) {
tasks.withType(Test) {
doFirst {
classpath = files(instrument.outputDir) + classpath + configurations.jacocoRuntime
}
}
}
}
task report(dependsOn: ['instrument', 'test']) {
doLast {
ant.taskdef(name: 'report',
classname: 'org.jacoco.ant.ReportTask',
classpath: configurations.jacocoAnt.asPath)
ant.report() {
executiondata {
ant.file(file: buildDir.path + '/reports/jacoco/jacoco-sonar/jacoco-coverage.exec')
}
structure(name: 'Example') {
classfiles {
fileset(dir: sourceSets.main.output.classesDir)
}
sourcefiles {
fileset(dir: 'src/main/java')
}
}
html(destdir: buildDir.path + '/reports/jacoco')
}
}
}
Here report task will create the offline instrumentation files of the project.
Finally, execute sonarqube task.
Then you can see the coverage of the powermocked classes also has included.
Execution command ./gradlew report sonarqube
Then go and see in your sonarqube host (localhost:9000).
You could try to use JaCoCo offline instrumentation instead of on-the-fly instrumentation as documented at https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo as long as https://github.com/powermock/powermock/issues/727 is not fixed which would make PowerMock compatible with JaCoCo on-the-fly instrumentation.
Alternatively you could use a different mocking framework, like e. g. JMockit. This is compatible with JaCoCo on-the-fly instrumentation as far as I remember.
I resigned to use gradle and jacoco. Now i'm using maven + cobertura + powermock and everything works without hacks. Why i'm using maven? Because i can't find how to produce xml code coverage report in cobertura using gradle.

Resources