I'm migrating from Maven to Gradle and I have an issue with generated sources. Here's the build.gradle of one of the subprojects
plugins {
id 'war'
id 'net.ltgt.apt-idea' version '0.15'
}
dependencies {
...
compileOnly 'com.querydsl:querydsl-apt:4.2.1:jpa'
compileOnly 'org.hibernate:hibernate-jpamodelgen:1.3.0.Final'
}
def generatedSources = "${buildDir}/generated/source/apt/main"
def generatedOutputDir = file("$generatedSources")
task generateSources(type: JavaCompile, group: 'build') {
doFirst {
generatedOutputDir.exists() || generatedOutputDir.mkdirs()
sourceSets.main.java.srcDirs = ["${generatedSources}", 'src/main/java']
}
options.compilerArgs += [
'-processor', '-proc:none',
'org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor,' +
'com.querydsl.apt.jpa.JPAAnnotationProcessor',
'-AaddSuppressWarningsAnnotation=true',
'-Aquerydsl.entityAccessors=true',
'-s', "${generatedSources}"
]
}
compileJava.finalizedBy generateSources
The classes are generated correctly, but right after the generation I receive the error "no suitable method found for..."
Basically the compilation fails because the generated classes are not taken into account during the compilation phase.
With the finalizedBy I was pretty sure it would work, but no..
Any ideas on how else I can get the class generation to run before the compileJava phase?
This line
compileJava.finalizedBy generateSources
Should be
compileJava.dependsOn generateSources
See https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:adding_dependencies_to_tasks
Related
I'm having trouble setting up jacoco coverage for my java project since I'm new to gradle. My final goal is to connect this to sonarqube. All my tests are in a separate module
structure:
./build.gradle
settings.gradle
./submodule1/build.gradle
./submodule1/src/main/java/prismoskills/Foo.java
./submodule2/build.gradle
./submodule2/src/main/java/com/project/prismoskills/Bar.java
./test/build.gradle
./test/src/test/java/prismoskills/TestFooBar.java
One way I can think of is to set additionalSourceDirs in test module and enable jacoco only in root and test module.
The problem with this approach is that my project has a lot of sub modules(which I haven't shown here) and I am having trouble passing additionalsourcedirs to test module's JacocoReport task in an automated way.
Also it looks like this use case can be handled in maven easily by referring to this
https://prismoskills.appspot.com/lessons/Maven/Chapter_06_-_Jacoco_report_aggregation.jsp
Any leads on how to proceed further with gradle will be appreciated. Thanks in advance
gradle version: 6.4
jacoco gradle plugin version: 0.8.5
I think the following solution should solve your problem. The idea is that:
JaCoCo exec file is generated for every project
at the end one XML report with all data is generated
It does the same for JUnit reports because it is easier to see all tests reports together in the root project instead of navigating between directories.
plugins {
id 'base'
id 'org.sonarqube' version '3.0'
}
allprojects {
apply plugin: 'jacoco'
apply plugin: 'project-report'
// ...
jacoco {
toolVersion = 0.8.5
}
}
subprojects {
// ...
test {
reports.html.enabled = false
useJunitPlatform()
finalizedBy jacocoTestReport
}
jacocoTestReport {
dependsOn test
reports.html.enabled = false
}
}
// ...
task testReport(type: TestReport) {
destinationDir = file("${buildDir}/reports/test")
reportOn subprojects*.test
}
task jacocoTestReport(type: JacocoReport) {
subprojects { subproject ->
subproject.tasks.findAll { it.extensions.findByType(JacocoTaskExtension) }.each { extendedTask ->
configure {
sourceSets subproject.sourceSets.main
if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {
executionData(extendedTask)
}
}
}
}
reports.xml.enabled = true
}
rootProject.getTasksByName('test', true).each {
it.finalizedBy(testReport)
it.finalizedBy(jacocoTestReport)
}
This line
if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {
is added to prevent build failures when some subprojects don't have tests at all.
Following can be defined in the build.gradle of root project. Jacoco plugin will be applied to all the submodules.
subprojects{
plugins{
id 'java'
id 'jacoco'
}
test.finalizedBy jacocoTestReport
}
Im having some issue and I had no luck figuring it out how to fix it.
I have a JavaFx Project which has Hibernate and Proguard. But whenever I try to run the task 'runProguard' fails with java.lang.module.ResolutionException.
What's puzzling me is the fact that my project doesnt use modules.
Is there anyway to fix this?
Task :runProguard FAILED Task ':runProguard' is not up-to-date
because: Task has not declared any outputs despite executing actions.
Starting process 'command ... Successfully started process 'command
'C:\Program Files\Java\openjdk-11_windows-x64_bin\bin\java.exe'' Error
occurred during initialization of boot layer
java.lang.module.ResolutionException: Modules java.activation and
activation export package javax.activation to module java.transaction
:runProguard (Thread[Daemon worker Thread 6,5,main]) completed. Took
1.094 secs.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:6.2.0'
}
}
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'org.beryx.runtime' version '1.7.1'
}
dependencies {
compile "org.controlsfx:controlsfx:11.0.0"
compile "eu.hansolo:tilesfx:11.13"
compile "com.jfoenix:jfoenix:9.0.9"
compile "org.apache.httpcomponents:httpclient:4.5.9"
compile "org.json:json:20180813"
compile "mysql:mysql-connector-java:8.0.17"
compile "org.jasypt:jasypt:1.9.3"
compile "com.sun.mail:javax.mail:1.6.2"
compile "commons-validator:commons-validator:1.6"
// https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0
compile "org.hibernate:hibernate-c3p0:5.4.7.Final"
// https://mvnrepository.com/artifact/org.hibernate/hibernate-envers
compile 'org.hibernate:hibernate-envers:5.4.8.Final'
// https://mvnrepository.com/artifact/de.jensd/fontawesomefx-commons
runtime group: 'de.jensd', name: 'fontawesomefx-commons', version: '11.0'
// https://mvnrepository.com/artifact/de.jensd/fontawesomefx-fontawesome
compile group: 'de.jensd', name: 'fontawesomefx-fontawesome', version: '4.7.0-9.1.2'
}
repositories {
jcenter()
mavenCentral()
}
javafx {
version = "13"
modules = ['javafx.controls', 'javafx.graphics', 'javafx.fxml']
}
mainClassName = 'Main'
runtime {
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
jpackage {
jpackageHome = 'C:/Program Files/Java/openjdk-14-jpackage+1-49_windows-x64_bin/'
if (org.gradle.internal.os.OperatingSystem.current().windows) {
installerType = 'msi'
imageOptions = []
installerOptions = ['--win-per-user-install',
'--win-dir-chooser',
'--win-menu',
'--win-shortcut',
'--verbose',
'--description', 'Test of proguard with jPackage',
'--name', 'Test-ProguardJPackage',
'--vendor', 'DoesItMatter']
}
}
}
jar {
dependsOn 'cleanAfterProguard'
manifest {
attributes(
'Main-Class': 'org.openjfx.Launcher'
)
}
from zipTree("${buildDir}/proguard/output.jar")
}
task cleanClasses(type: Delete) {
delete "${buildDir}/classes/java/main"
delete "${buildDir}/resources/java/main"
}
classes.dependsOn(cleanClasses)
// 2.2 Add proguard task
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: classes) {
injars project.sourceSets.main.output
outjars "${buildDir}/proguard/output.jar"
libraryjars project.sourceSets.main.compileClasspath
configuration 'proguard.conf'
}
// 2.3 Clean after proguard task
task cleanAfterProguard(type: Delete, dependsOn: proguard) {
delete "${buildDir}/classes/java/main"
delete "${buildDir}/resources/java/main"
}
// 2.4 Extract output jar to buildDir
task unpackProguardOutput(type: Copy, dependsOn: cleanAfterProguard) {
from zipTree("${buildDir}/proguard/output.jar")
into file("${buildDir}/classes/java/main")
}
// 3. Create a task to run the app with the proguarded buildDir
task runProguard(type: JavaExec, dependsOn: unpackProguardOutput) {
classpath = sourceSets.main.runtimeClasspath
jvmArgs = ['--module-path', classpath.asPath,
'--add-modules', 'javafx.controls,javafx.fxml']
main = 'Main' // <-- this name will depend on the proguard result
}
jar.dependsOn(unpackProguardOutput)
This is the repo:
https://github.com/KenobySky/hellofx
Here's the Error:
FAILURE: Build failed with an exception.
Where: Build file '/home/wieland/GitGradlePackaging/build.gradle' line: 22
What went wrong: A problem occurred evaluating root project 'GitGradlePackaging'.
Could not get unknown property 'org' for object of type org.gradle.api.internal.initialization.DefaultScriptHandler.
And Here's my build.gradle File:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at https://docs.gradle.org/4.6/userguide/tutorial_java_projects.html
*/
//From example: http://mrhaki.blogspot.co.at/2015/04/gradle-goodness-use-git-commit-id-in.html
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
}
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building an application
id 'application'
// Apply the groovy plugin to also add support for Groovy (needed for Spock)
id 'groovy'
id 'distribution'
}
// Set version
project.version = mainProjectVersion + " - " + githash
project.ext.set("wholeVersion", "$project.version - $githash")
project.ext.set("buildtimestamp", "2000-01-01 00:00")
def versionfilename = "versioninfo.txt"
def GROUP_DEBUG = 'Debug'
// Task to print project infos
task debugInitialSettings {
group = GROUP_DEBUG
doLast {
println 'Version: ' + project.wholeVersion
println 'Timestamp: ' + project.buildtimestamp
println 'Filename: ' + project.name
}
}
// To add the githash to zip
task renameZip {
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.zip")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.zip")
}
}
distZip.finalizedBy renameZip
// To add the githash to tar
task renameTar{
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.tar")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.tar")
}
}
distTar.finalizedBy renameTar
// Define the main class for the application
mainClassName = 'App'
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:23.0'
// Use the latest Groovy version for Spock testing
testCompile 'org.codehaus.groovy:groovy-all:2.4.13'
// Use the awesome Spock testing and specification framework even with Java
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile 'junit:junit:4.12'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
//To generate Testreports as HTML
test {
reports {
junitXml.enabled = false
html.enabled = true
}
}
distributions {
main {
contents {
from { 'build/docs' }
into ('reports') {
from 'build/reports'
}
}
}
}
//To make sure that test and javadoc ran before zip and tar
distTar.dependsOn test
distZip.dependsOn test
distTar.dependsOn javadoc
distZip.dependsOn javadoc
Please keep in mind I have not much knowledge about gradle as I'm just starting to learn it!
Thanks in advance :)
You have to move the githash definition outside the buildscript block
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
The reason is that when the buildscript block is evaluated line by line, its dependencies are not yet loaded. When the rest of the script is evaluated, the dependencies of the buildscript block have already been loaded. This is actually the reason for the buildscript block existence: to be run before the rest of the build and prepare the setup.
I am having difficulty combining Jacoco coverage report for a Gradle multi-project. For simplicity, I have created a simplified version that is structured as follows. I have the example project on GitHub.
+ root
+ common-a
+ common-b
+ project-a
+ project-b
The root, project-a, and project-b are Spring Boot applications. For some context, a project is meant to be a micro-service. Thus, the root project is simply running all micro-services in one process.
Not all projects have unit and/or integration tests. common-a subproject does not have any tests; common-b, project-a, and project-b projects have unit and integration tests; the root project has only integration tests.
The Jacoco coverage reports for subprojects are correct. It is able to combine both unit and integration tests into one cohesive report. However, the root project does not produce the cohesive report correctly.
I have tried a number of solutions with any success. Most of the solutions I found assume that the root project is simply a logical container and only the subprojects has test code. The results of the solutions I tried fall into one of the following three categories.
No Jacoco report generated at all; the build/reports/jacoco directory is missing
Partial Jacoco report for only sources in root project
Full Jacoco coverage report for root and subproject but 0% coverage; it is supposed to be 100% coverage
The following is the current build.gradle file.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
}
}
// settings for all projects
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
group 'io.github.chriszhong'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
repositories {
jcenter()
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:2.0.5.RELEASE'
}
}
sourceSets {
integrationTest {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
}
}
configurations {
integrationTestCompile {
extendsFrom testCompile
}
integrationTestRuntime {
extendsFrom testRuntime
}
}
idea {
module {
testSourceDirs += sourceSets.integrationTest.java.srcDirs
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
}
}
task integrationTest(type: Test) {
check {
dependsOn integrationTest
}
testClassesDir sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
task testReport(type: TestReport) {
dependsOn check
destinationDir file("${reporting.baseDir}/unified/html")
reportOn test, integrationTest
}
task jacocoMerge(type: JacocoMerge) {
dependsOn check
executionData test, integrationTest
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
tasks.withType(Test) {
reports {
html {
destination file("${reporting.baseDir}/${task.name}/html")
}
}
}
tasks.withType(JacocoReport) {
dependsOn jacocoMerge
executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
}
}
apply plugin: 'spring-boot'
version '1.0-SNAPSHOT'
dependencies {
compile project(':project-a')
compile project(':project-b')
testCompile 'junit:junit'
integrationTestCompile 'org.springframework.boot:spring-boot-starter-test'
}
testReport {
dependsOn check, subprojects.testReport
reportOn test, integrationTest, subprojects.test, subprojects.integrationTest
}
jacocoMerge {
dependsOn check, subprojects.jacocoMerge
executionData test, integrationTest, subprojects.jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
//jacocoTestReport {
// dependsOn jacocoMerge
// executionData test, integrationTest, subprojects.test, subprojects.integrationTest
// executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
// sourceDirectories = files(sourceSets.main.java.srcDirs, subprojects.sourceSets.main.java.srcDirs)
// classDirectories = files(sourceSets.main.output.classesDir, subprojects.sourceSets.main.output.classesDir)
//}
task wrapper(type: Wrapper) {
gradleVersion '2.14'
distributionUrl "https://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}
I have been banging my head at this problem for the past week and is at my wits end. I greatly appreciate any help I can get in resolving this problem.
I'm trying to get Cucumber running from Gradle. When I try to execute Cucumber tests I get
Error: Could not find or load main class cucumber.api.cli.Main
Gradle downloaded the cucumber-jvm-1.1.3.pom file but none of the cucumber .jar files. Here is my build.gradle:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'info.cukes:cucumber-jvm:1.1.3'
}
configurations {
cucumberRuntime {
extendsFrom testRuntime
}
}
task runCucTests(type: JavaExec) {
main = "cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = ['-f', 'pretty', '--glue', 'gradle.cucumber', 'src/test/resources', '--tags #complete', ' --format junit:target/reports/cucumber-junit-report/allcukes.xml', '--format pretty', '--format html:target/reports/cucumber-html-report']
}
I've tried changing the dependency to runtime and changing the cucumberRuntime to extend from runtime but the result is the same.
Why isn't gradle recognizing that it needs to download the cucumber .jar files?
Thanks.
cucumber-jvm is the parent group
cucumber.api.cli.Main requires cucumber-core
Use below:
dependencies {
compile "info.cukes:cucumber-core:1.1.3"
}
This will download the required jar.