Trying to create a small custom gradle task for Spring Boot that originally looks like this:
gradle bootRun --debug-jvm
The task should look like this: gradle debugRun
I tried this but it does not work:
task debugRun(dependsOn: 'bootRun') << {
applicationDefaultJvmArgs = ['--debug-jvm']
}
How can I pass this debug-flag to the bootRun task?
It isn't sufficient for your debug run task to depend on the bootRun task. It needs to modify the existing bootRun task to enable debugging. You can do that by checking for the debugRun task in Gradle's task graph. If it's there, you set the bootRun task's debug property to true:
task debugRun(dependsOn:bootRun) {
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(debugRun)) {
bootRun {
debug = true
}
}
}
}
Related
I want to define two different versions of the bootRun task in a Spring boot application using Gradle. This is my attempt, which worked for customizing a single bootRun task. But with multiple tasks containing bootRun, the last bootRun overrides the previous ones.
task local {
bootRun {
systemProperty "spring.profiles.active", "dev,postgres"
jvmArgs "--add-opens=java.base/java.util=ALL-UNNAMED", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
}
}
local.finalizedBy bootRun
task prod {
bootRun {
systemProperty "spring.profiles.active", "postgres"
jvmArgs "--add-opens=java.base/java.util=ALL-UNNAMED"
}
}
prod.finalizedBy bootRun
Here, when I run ./gradlew :local, the spring profiles are only postgres. When I comment out the prod task, I get both dev,postgres as expected.
As currently written, your local and prod tasks are default tasks that aren't really doing anything. Your use of bootRun within their configuration is altering the configuration of the existing bootRun task that Spring Boot's Gradle plugin defines.
When you define the tasks, you need to tell Gradle that they are a BootRun task:
task local(type: org.springframework.boot.gradle.tasks.run.BootRun) {
// …
}
You also need to configure the main class name and the classpath of your new task. You probably want those to be the same as the default bootRun task:
task local(type: org.springframework.boot.gradle.tasks.run.BootRun) {
mainClass = bootRun.mainClass
classpath = bootRun.classpath
}
You can then customize the system properties and JVM arguments as you were before. Putting this all together, you can configure your local and prod tasks like this:
task local(type: org.springframework.boot.gradle.tasks.run.BootRun) {
mainClass = bootRun.mainClass
classpath = bootRun.classpath
systemProperty "spring.profiles.active", "dev,postgres"
jvmArgs "--add-opens=java.base/java.util=ALL-UNNAMED", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
}
task prod(type: org.springframework.boot.gradle.tasks.run.BootRun) {
mainClass = bootRun.mainClass
classpath = bootRun.classpath
systemProperty "spring.profiles.active", "postgres"
jvmArgs "--add-opens=java.base/java.util=ALL-UNNAMED"
}
I use this gradle command to execute my UI-tests:
./gradlew connectedDebugAndroidTest -PUiTest
I want to define a custom gradle task that executes my UI-tests, so I could this:
task runUiTests() {
dependsOn("connectedDebugAndroidTest")
}
How can I pass the parameter -PUiTest in my custom gradle task to the connectedDebugAndroidTest task?
I need to extend the gradle war task with some doFirst and doLast commands to compile my sencha frontend in production state.
I know to extend a task I need to add task.doFirst {} but this is not working with war. I did some tests using other tasks like
clean {
doFirst {
println "test"
}
}
This is working ... but with war it isn't
war {
doFirst {
println "test"
}
}
My main idea was to remove src/main/webapp from the from list and execute sencha-cmd sencha app build -c --destination $war/ production
You should create a separate task for the sencha compilation with it's own inputs/outputs so Gradle can perform up-to-date checking (so it can be skipped if not necessary). You can then wire the task into the gradle DAG via Task.dependsOn(...)
task compileSencha(type:Exec) {
inputs.dir 'src/main/sencha'
outputs.dir "$buildDir/sencha"
commandLine 'sencha', 'app', 'build', file('src/main/sencha').absolutePath, file("$buildDir/sencha").absolutePath
}
war {
from "$buildDir/sencha"
dependsOn compileSencha
}
I have a gradle project in scala to which I am trying to add sonarRunner. Things are working fine, but compilation and test is running twice on executing task sonarRunner as SonarRunner adds test as a dependency. However, scoverage always recompiles the code for instrumentation and then runs the tests.
Is there a way to avoid running the tests twice. I tried ignoring tests in sonarRunner task, but then test task won't run at all. I tried guarding ignore test in sonarRunner task by something like below mentioned code and that basically does not do anything.
task sonarRunner {
test {
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask('sonarRunner')) {
enabled = false
}
}
}
dependsOn 'reportScoverage'
}
Any suggestion will be helpful.
You can remove the dependency to the test task by overriding the sonarRunner task's dependencies.
tasks.sonarRunner {
dependsOn = []
}
I've got a very simple multiproject build like below:
module1, which generates a public API jar and exposes it through "publicAPI" configuration:
configurations {
publicAPI
}
task generatePublicAPI(type: Jar) {
outputs.upToDateWhen { false }
baseName 'public-api'
from sourceSets.main.output
}
artifacts {
publicAPI generatePublicAPI
}
module2, which uses the public API jar (by referencing 'publicAPI' configuration defined in module1) to generate a application jar:
configurations {
generateApplication
}
dependencies {
generateApplication project(path: ':module1', configuration: 'publicAPI')
}
task jarApp(type: Jar) {
baseName 'app'
from configurations.generateApplication.collect {
it.isDirectory() ? it : zipTree(it)
}
}
Now, when I execute 'gradle :module2:jarApp" task, I got the following error:
Cannot expand ZIP
'/home/picasso/Documents/GradlePlayground/module1/build/libs/public-api.jar'
as it does not exist
and I can see that gradle was not trying to execute 'generatePublicAPI' of module1.
However, if I make "jarApp" task depends on "generatePublicAPI" task explicitly,
task jarApp(dependsOn: 'module1:generatePublicAPI', type: Jar) {...}
then everything's fine.
BUT, wouldn't this approach against one of the purpose of using dependency configuration so that I don't have to worry about the details of how module1 is built, e.g. which task generates the jar and what artifacts it produces?
I thought gradle is able to work out the tasks it needs to execute by following along the "route" of the referenced dependency configuration.
Am I missing something here so that "generatePublicAPI" task can be executed automatically without have to declare "dependsOn" explicitly for "createApp" task?
I asked the same question on Gradleware's forum and got the answer from one of the core developer, here's the link.
Basically, the issue is that collect method returns a new collection but gradle has no way to know that this new collection was generated from the configuration, therefore it couldn't infer which task to execute.
The solution is instead of declaring a dependency on a task, declare a dependency on the actual configuration instead like the following:
task jarApp(dependsOn: configurations.generateApplication, type: Jar)