QueryDSL, spring-boot & Gradle - gradle

I was hoping to bring querydsl into my spring-boot project via gradle. Despite finding a couple of examples online, none of them actually work for me because of issues with dependencies (I think). According to the QueryDSL support forum, gradle is not supported yet. But I was wondering with all the gradle & spring-boot being created if someone has managed to make it work yet?
Here is my build.gradle:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'war'
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
}
}
repositories {
mavenCentral()
maven { url: "http://repo.spring.io/libs-snapshot" }
// maven { url: "http://repo.spring.io/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RC5")
compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.0.RC5")
compile("org.springframework:spring-orm:4.0.0.RC1")
compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
compile("com.h2database:h2:1.3.172")
compile("joda-time:joda-time:2.3")
compile("org.thymeleaf:thymeleaf-spring4")
compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
compile('org.codehaus.groovy:groovy-all:2.2.1')
compile('org.jadira.usertype:usertype.jodatime:2.0.1')
// this line fails
querydslapt "com.mysema.querydsl:querydsl-apt:3.3.2"
testCompile('org.spockframework:spock-core:0.7-groovy-2.0') {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
testCompile("junit:junit")
}
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
sourceSets {
main {
generated {
java {
srcDirs = ['src/main/generated']
}
}
java {
srcDirs = []
}
groovy {
srcDirs = ['src/main/groovy', 'src/main/java']
}
resources {
srcDirs = ['src/main/resources']
}
output.resourcesDir = "build/classes/main"
}
test {
java {
srcDirs = []
}
groovy {
srcDirs = ['src/test/groovy', 'src/test/java']
}
resources {
srcDirs = ['src/test/resources']
}
output.resourcesDir = "build/classes/test"
}
}
configurations {
// not really sure what this is, I see it in examples but not in documentation
querydslapt
}
task generateQueryDSL(type: JavaCompile, group: 'build', description: 'Generates the QueryDSL query types') {
source = sourceSets.main.java
classpath = configurations.compile + configurations.querydslapt
options.compilerArgs = [
"-proc:only",
"-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
]
destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}
compileJava {
dependsOn generateQueryDSL
source generateQueryDSL.destinationDir
}
compileGeneratedJava {
dependsOn generateQueryDSL
options.warnings = false
classpath += sourceSets.main.runtimeClasspath
}
clean {
delete sourceSets.generated.java.srcDirs
}
idea {
module {
sourceDirs += file('src/main/generated')
}
}
But gradle fails with:
Could not find method querydslapt() for arguments [com.mysema.querydsl:querydsl-apt:3.3.2]
I have tried changing the querydsl-apt version to earlier ones but I get the same error.

Working configuration for Spring Boot 1.3.5 and supported QueryDSL, tested with gradle 2.14.
ext {
queryDslVersion = '3.6.3'
javaGeneratedSources = file("$buildDir/generated-sources/java")
}
compileJava {
doFirst {
javaGeneratedSources.mkdirs()
}
options.compilerArgs += [
'-parameters', '-s', javaGeneratedSources
]
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile "com.mysema.querydsl:querydsl-jpa:$queryDslVersion"
compileOnly "com.mysema.querydsl:querydsl-apt:$queryDslVersion:jpa"
}
Complete project source code: spring-boot-querydsl

You probably need to do at least 2 things:
Declare the "querydslapt" configuration before you use it
Add querydsl-jpa (or whatever flavours you need) to your "compile" configuration.
Then you will have the classpath set up, but the apt bit will not do anything without some more configuration (as you found no doubt from the querydsl support forum). The apt but is used to generate some code that you then need to compile and use in your application code (the "Q*" classes corresponding to your domain objects). You could drive that from a build task in gradle I imagine (it only has to run once for every change in the domain objects).

Related

Gradle Multi-Project Integration Tests with Junit5

How can I create integrations tests using Gradle 5.2 and JUnit 5.3 in a multi-project build file?
This is my current build file:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin:1.6.10"
classpath 'org.owasp:dependency-check-gradle:5.0.0-M2'
}
}
allprojects {
defaultTasks 'clean', 'build', 'publish', 'installDist'
group = 'coyote'
version = '0.1.0'
}
subprojects {
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: "com.github.spotbugs"
apply plugin: 'org.owasp.dependencycheck'
apply plugin: 'maven-publish'
apply plugin: 'application'
apply plugin: 'eclipse'
apply plugin: 'idea'
repositories {
jcenter()
mavenCentral()
}
dependencies {
testImplementation ("org.junit.jupiter:junit-jupiter-api:5.3.2")
testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.3.2")
spotbugsPlugins ("com.h3xstream.findsecbugs:findsecbugs-plugin:1.8.0")
}
tasks.withType(Test) {
useJUnitPlatform()
}
apply from: "$rootDir/integration-test.gradle"
check.dependsOn jacocoTestCoverageVerification
check.dependsOn dependencyCheckAnalyze
spotbugs {
effort = "max"
reportLevel = "low"
ignoreFailures = true
showProgress = true
}
jacocoTestReport {
reports {
xml.enabled true
html.enabled true
}
}
check.dependsOn jacocoTestReport
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled false
html.enabled true
}
}
}
The integration-test.gradle file I am applying on line 46 contains the following:
sourceSets {
itest {
compileClasspath += sourceSets.main.output + configurations.testCompile
runtimeClasspath += output + compileClasspath + configurations.testRuntime
}
}
idea {
module {
testSourceDirs += sourceSets.itest.java.srcDirs
testResourceDirs += sourceSets.itest.resources.srcDirs
scopes.TEST.plus += [configurations.itestCompile]
}
}
task itest(type: Test) {
description = 'Runs the integration tests.'
group = 'verification'
testClassesDirs = sourceSets.itest.output.classesDirs
classpath = sourceSets.itest.runtimeClasspath
outputs.upToDateWhen { false }
}
Everything seems to work well within Intellij, but JUnit5 is not being added to the classpath, so any tests in the itest directories cannot find the JUnit libraries.
Running gradlew itest fails with similar results with the JUnit classes not being found.
I have tried to add use useJUnitPlatform() directly in the itest task, but with no success. I have also tried placing everything in the build.gradle file with no success.
Eventually, I'd like to use the same pattern to define load and security testing, running them separately as part of a CI/CD pipeline so placing everything neatly in their own directories under their respective projects is preferred to mixing everything in one test directory and using tags.
This is also helping other teams model CI/CD practices, so using Gradle 5 and JUnit 5 as designed is preferred as opposed to work-arounds or hacks to make things work. It's acceptable to learn that these versions don't work together or that there are currently defects\issues preventing this approach. Hopefully this is not the issue and I'm just missing something simple.
The solution is I needed to include the JUnit 5 dependencies myself. The following is the correct integration-test.gradle file:
sourceSets {
itest {
compileClasspath += sourceSets.main.output + configurations.testCompile
runtimeClasspath += output + compileClasspath + configurations.testRuntime
}
}
idea {
module {
testSourceDirs += sourceSets.itest.java.srcDirs
testResourceDirs += sourceSets.itest.resources.srcDirs
scopes.TEST.plus += [configurations.itestCompile]
}
}
dependencies {
itestImplementation ("org.junit.jupiter:junit-jupiter-api:5.3.2")
itestRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.3.2")
}
task itest(type: Test) {
description = 'Runs the integration tests.'
group = 'verification'
testClassesDirs = sourceSets.itest.output.classesDirs
classpath = sourceSets.itest.runtimeClasspath
outputs.upToDateWhen { false }
}

Define the generator code location using gradle to build xtext and xtend

I'm trying to create a first project using xText and xTend building with gradle.
I created the grammar following the guidance in the xText documentation and also created the xtend generators.
In eclipse the code generates to src-gen folder as expected.
When I created the gradle script, also following the http://xtext.github.io/xtext-gradle-plugin/xtext-builder.html to build my code instead of generating the code in 'src-gen' folder it generates in 'build' folder.
Is there any way to change this folder from build to src-gen in the gradle? I tried a lot of things and I got always errors.
Complete code of grade script:
apply plugin: 'org.xtext.builder'
dependencies {
xtextLanguages 'com.example.mylang:mylang:1.0.0-SNAPSHOT'
}
xtext {
languages {
mylang{
setup = 'com.example.MyLangStandaloneSetup'
generator.outlet.producesJava = true
}
}
sourceSets {
main {
srcDir 'src/main/xtext'
xtendOutputDir 'src-gen'
}
}
}
you can configure that in the source set
sourceSets {
main.xtendOutputDir = 'xtend-gen'
}
e.g.
plugins {
id "org.xtext.xtend" version "1.0.21"
}
apply plugin: 'java'
apply plugin: 'org.xtext.xtend'
sourceSets {
main.java.srcDirs = ['src','xtend-gen']
main.xtendOutputDir = 'xtend-gen'
}
repositories {
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
compile 'org.eclipse.xtext:org.eclipse.xtext.xbase.lib:2.13.0'
}
or for the xtxt builder plugin
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'org.xtext:xtext-gradle-plugin:1.0.21'
}
}
plugins {
id "org.xtext.builder" version "1.0.21"
}
repositories {
mavenLocal()
jcenter()
}
dependencies {
xtextLanguages 'org.xtext.example.mydslfoo:org.xtext.example.mydslfoo:1.0.0-SNAPSHOT'
}
xtext {
version '2.13.0'
languages {
mydslfoo {
setup = 'org.xtext.example.mydslfoo.MyDslFooStandaloneSetup'
generator {
outlets {
HEROES {
}
}
}
}
}
sourceSets {
main {
srcDir 'src'
output {
dir(xtext.languages.mydslfoo.generator.outlet, 'src-gen')
}
}
}
}

Upload only war/jar files in gradle(restrict zip/tar generation and upload)

My build script is like as follows. I use gradle build command to build and gradle upload command to upload the artifact. My problem is a tar,zip file is also generated with this command and get uploaded. I dont want it. Only things I would like to get uploaded is 'jar' and 'war' files.
I have also a related question posted by me yesterday here.
More details(I have excluded some unwanted code)
build file in root
allprojects {
apply plugin: 'maven'
group = 'groupid'
version = '1.0-SNAPSHOT'
}
subprojects {
apply plugin: 'java'
sourceCompatibility = 1.7
targetCompatibility = 1.7
repositories {
maven {
credentials {
username "$nexusUser"
password "$nexusPass"
}
url "$nexusUrl"
}
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "$nexusSnapshotUrl") {
authentication(userName: "$nexusUser", password: "$nexusPass")
}
}
}
}
}
ext.comlib = [ // Groovy map literal
junit3: "junit:junit:3.8",
junit4: "junit:junit:4.9",
spring_core: "org.springframework:spring-core:3.1",
hibernate_validator : "org.hibernate:hibernate-validator:5.1.3.Final",
spring_core : "org.springframework.security:spring-security-core:4.0.2.RELEASE",
spring_security_web: "org.springframework.security:spring-security-web:4.0.2.RELEASE",
spring_security_config: "org.springframework.security:spring-security-config:4.0.2.RELEASE",
spring_boot_starter_test: "org.springframework.boot:spring-boot-starter-test:1.2.5.RELEASE",
spring_boot_starter_actuator: "org.springframework.boot:spring-boot-starter-actuator:1.2.5.RELEASE",
spring_boot_plugin_gradle: "org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE",
asciidoctor_gradle_plugin: "org.asciidoctor:asciidoctor-gradle-plugin:1.5.1",
asciidoctor_pdf_plugin: "org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.9"/*,
sl4j_api: "org.slf4j:slf4j-api:1.7.12",
sl4j_log4j: "org.slf4j:slf4j-log4j12:1.7.12",
logback_classic: "ch.qos.logback:logback-classic:1.1.3",
logback_core: "ch.qos.logback:logback-core:1.1.3"*/
]
build file in sub module
apply plugin: 'spring-boot'
group = 'com.group.id'
apply from: "../build.gradle"
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
apply plugin: 'war'
description = 'module name'
dependencies {
compile "someothermodule:commonapi:1.0.0-SNAPSHOT"
compile "io.springfox:springfox-swagger2:2.0.1"
compile project(':dependingproject1:dependingproject2')
compile comlib.spring_boot_starter_actuator
compile comlib.spring_core
compile comlib.spring_security_web
compile comlib.spring_security_config
testCompile(comlib.spring_boot_starter_test) {
exclude(module: 'commons-logging')
}
testCompile comlib.junit4
providedCompile comlib_app.spring_boot_plugin_tomcat
testCompile "io.springfox:springfox-staticdocs:2.0.3"
testCompile "org.springframework:spring-test:4.1.7.RELEASE"
}
ext {
swaggerOutputDir = file("src/docs/asciidoc/generated")
asciiDocOutputDir = file("${buildDir}/asciidoc")
}
test {
systemProperty 'org.springframework.restdocs.outputDir', asciiDocOutputDir
systemProperty 'io.springfox.staticdocs.outputDir', swaggerOutputDir
}
//spring boot plugin
buildscript {
repositories {
maven {
credentials {
username "$nexusUser"
password "$nexusPass"
}
url "$nexusCentral"
}
maven {
credentials {
username "$nexusUser"
password "$nexusPass"
}
url "$nexusThirdParty"
}
}
dependencies {
classpath(comlib.spring_boot_plugin_gradle)
}
}
Included the following code snippet in my gradle file
[distZip, distTar].each { task -> configurations.archives.artifacts.removeAll
{ it.class.simpleName == "ArchivePublishArtifact" && it.archiveTask == task }
task.enabled = false
}
For more details refer this link. Its issue with spring boot plugin.
arjuncc's solution doesn't seem to work on Gradle 4.10.2, so here's one that works and uses public APIs, hopefully it will continue to work.
configurations.archives.artifacts.removeAll {
// exclude from the archives configuration all artifacts that were generated by distZip & distTar
def depTasks = it.getBuildDependencies().getDependencies()
depTasks.contains(distZip) || depTasks.contains(distTar)
}
More or less the same as ajuncc's solution, but perhaps a bit more simple. Remove all .tar artifacts from the archives configuration:
configurations.archives.artifacts.removeAll {PublishArtifact publishArtifact -> publishArtifact.type == 'tar'}

How to apply Cobertura plugin to all projects or all subprojects

I'm trying to apply the Cobertura plugin to all projects and subprojects in my Gradle build scripts. However, the scripts are unable to find the plugin when applied to all. Here is what I've got:
buildscript {
repositories {
jcenter()
}
}
allprojects {
beforeEvaluate {
project.buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'net.saliman:gradle-cobertura-plugin:2.2.7'
}
}
}
}
subprojects {
apply plugin: 'net.saliman.cobertura'
}
This is how build.gradle should look like:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'net.saliman:gradle-cobertura-plugin:2.2.7'
}
}
allprojects {
apply plugin: 'net.saliman.cobertura'
}
You may also find that you want to merge all your subprojects cobertura reports into one beautiful top level report for the entire project.
To do this you will need cobertura gradle plugin 2.2+ I believe and the configuration for that is something like:
// note - all non-cobertura config is stripped out of this example
allprojects {
apply plugin: 'cobertura'
}
subprojects {
cobertura {
coverageIgnoreTrivial = true
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "net.saliman:gradle-cobertura-plugin:2.2.2"
}
}
def files = subprojects.collect { new File(it.projectDir, '/build/cobertura/cobertura.ser') }
cobertura {
coverageFormats = [ 'xml', 'html' ]
coverageSourceDirs = subprojects.sourceSets.main.allSource.srcDirs.flatten()
coverageMergeDatafiles = files
}
test.dependsOn(subprojects.test)
which is from syncsynchalt's great comment on the issue here:
https://github.com/stevesaliman/gradle-cobertura-plugin/issues/10

where to put sourceSets in multiple projects gradle

I have a multiple projects gradle, in the top gradle is
subprojects {
apply plugin: "java"
sourceSets {
main {
scala {
srcDirs = ['src/main/scala', 'src/main/java']
}
java {
srcDirs = []
}
}
}
repositories {
mavenCentral()
maven {
url "http://repo.springsource.org/milestone"
}
}
}
But it complains
> Could not find method sourceSets() for arguments [build_vgdvugn6hqrvg7eo53afh1229$_run_closure1_closure2#19962194] on root project 'testCom'.
So where should I put sourceSets?
The error message is a bit misleading, but before you can configure sourceSets.main.scala, you'll have to apply the scala plugin.

Resources