copy task is not working after the javaexec task is completed - gradle

Below is my code in build.gradle
`tasks.register("javaExe",JavaExec::class.java) {
main = "com.company.main"
val subproject = project(":utils").extensions.getByName("sourceSets") as SourceSetContainer
classpath = subproject["main"].runtimeClasspath
val baseDirectory = project.projectDir.absolutePath
val URL = environment["URL"]
val DBURL = environment["DBURL"]
val JREURL = environment["JREURL"]
args(baseDirectory, URL, DBURL, JREURL)
}
tasks.register("copydep",Copy::class) {
shouldRunAfter("javaExe")
//some copy task
}
tasks.register("runBuild") {
dependsOn("javaExe")
dependsOn("copydep")
doLast{
//some code
}
}`
when I run the runBuild task it should execute in order like javaExe,copydep and runBuild but the copydep task is not working always.
I have verified the source and destination path location both are preset.
when we remove the javaExe depandencies copy task working perfectly.

Related

Child process exited with code 1 LibGDX jPackageImage task

I am using jpackage to convert my libgdx game to an executable file. I am following this tutorial to do so. The jpackageImage task works perfectly fine but when the exe is created and I run it, it doesn't run but rather gives me an error: Child process exited with code 1 I am unaware what is causing this.
I am on windows 11 and im using JDK 18.0.1.1.
The JDK is set to JAVA_HOME which is set to the correct PATH.
I am using Badass-Runtime plugin as well which is defined in the first line of my build.gradle file.
Here is my build.gradle file for desktop:
plugins { id 'org.beryx.runtime' version '1.8.4' }
sourceCompatibility = 1.7
sourceSets.main.java.srcDirs = ["src/"]
sourceSets.main.resources.srcDirs = ["../core/assets"]
mainClassName = "com.mygdx.game.desktop.DesktopLauncher"
def osName = System.getProperty('os.name').toLowerCase(Locale.ROOT)
project.ext.assetsDir = new File("../core/assets")
task runGame(dependsOn: classes, type: JavaExec) {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
}
task debug(dependsOn: classes, type: JavaExec) {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
debug = true
}
task dist(type: Jar) {
manifest {
attributes 'Main-Class': project.mainClassName
}
dependsOn configurations.runtimeClasspath
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar
destinationDirectory = file("$buildDir/lib")
}
jpackageImage.dependsOn dist
dist.dependsOn classes
eclipse.project.name = appName + "-desktop"
runtime {
options = ['--strip-debug',
'--compress', '2',
'--no-header-files',
'--no-man-pages',
'--strip-native-commands',
'--vm', 'server']
modules = ['java.base',
'java.desktop',
'jdk.unsupported']
distDir = file(buildDir)
jpackage {
jpackageHome = 'C:\\Users\\pc\\.jdks\\openjdk-18.0.1.1'
mainJar = dist.archiveFileName.get()
if (osName.contains('windows')) {
imageOptions = ["--icon", file("../icons/icon.ico")]
} else if (osName.contains('linux')) {
imageOptions = ["--icon", file("../icons/icon.png")]
} else if (osName.contains('mac')) {
imageOptions = ["--icon", file("../icons/icon.icns")]
}
}
}
Is it this bug? bugs.openjdk.org/browse/JDK-8284067 which triggers because your code exits with 1. Try doing with System.exit(0); , there is a workaround listed as well.

Gradle Kotlin DSL Replace Token

In my code there is const val VERSION = $version.
I want to replace $version with real version string which is in my build.gradle.kts.
How can I do this?
Working example here.
One way is to use a template file (stored outside of src tree). Let's call it TemplateVersion.kt:
class Version() {
val version = "__VERSION";
}
and then in build.gradle.kts, as initial part of the compileKotlin task, we generate Version.kt from TemplateVersion.kt:
val sourceFile = File(rootDir.absolutePath + "/resources/TemplateVersion.kt")
val propFile = File(rootDir.absolutePath + "/gradle.properties")
val destFile = File(rootDir.absolutePath + "/src/main/kotlin/${targetPackage}/Version.kt")
tasks.register("generateVersion") {
inputs.file(sourceFile)
inputs.file(propFile)
outputs.file(destFile)
doFirst {
generateVersion()
}
}
tasks.named("compileKotlin") {
dependsOn("generateVersion")
}
fun generateVersion() {
val version: String by project
val rootDir: File by project
val inputStream: InputStream = sourceFile.inputStream()
destFile.printWriter().use { out ->
inputStream.bufferedReader().forEachLine { inputLine ->
val newLine = inputLine.replace("__VERSION", version)
out.println(newLine)
}
}
inputStream.close()
}
where gradle.properties is:
version=5.1.50
It is trivially easy to add more fields to Version.kt, such as a build-timestamp.
(Edit: This has been updated with a proper generateVersion task that will detect changes to gradle.properties. The compileKotlin task will invoke this task).

How extend task provided by plugin?

I have kotlin2js plugin with task compileKotlin2Js. I configure it like this:
val compileKotlin2Js: Kotlin2JsCompile by tasks
compileKotlin2Js.kotlinOptions {
main = "call"
outputFile = "${projectDir}/build/app.js"
}
Now I want to create similar task, but with other kotlinOptions. For example:
.kotlinOptions {
main = "noCall"
outputFile = "${projectDir}/build/lib.js"
}
How to do it?
UPDATE: I also tried to do some thing like this:
tasks.register<Kotlin2JsCompile>("myCompile2Js") {
kotlinOptions {
main = "noCall"
outputFile = "${projectDir}/build/lib.js"
}
}
But it produce error:
Execution failed for task ':myCompile2Js'.
> lateinit property destinationDirProvider has not been initialized
I also tried to specify destinationDir. Error disappear, but such task does not produce any build.
I haven't tested it, but I believe something like the following should do the trick:
tasks.register<Kotlin2JsCompile>("myCompile2Js") {
kotlinOptions {
main = "noCall"
outputFile = "${projectDir}/build/lib.js"
}
}
Or if you need a reference to the task later on:
val myCompile2Js by tasks.creating(Kotlin2JsCompile::class)
myCompile2Js.kotlinOptions {
main = "noCall"
outputFile = "${projectDir}/build/lib.js"
}

Custom gradle script for Detekt with multi-module project

I'm trying to create a custom gradle task that will run the different detekt profiles I have setup.
Here is my Detekt config:
detekt {
version = "1.0.0.RC6-4"
profile("main") {
input = "$projectDir/app/src/main/java"
output = "$projectDir/app/build/reports/detekt"
config = "$projectDir/config/detekt-config.yml"
}
profile("app") {
input = "$projectDir/app/src/main/java"
output = "$projectDir/app/build/reports/detekt"
}
profile("database") {
input = "$projectDir/database/src/main/java"
output = "$projectDir/database/build/reports/detekt"
}
profile("logging") {
input = "$projectDir/logging/src/main/java"
output = "$projectDir/logging/build/reports/detekt"
}
profile("network") {
input = "$projectDir/network/src/main/java"
output = "$projectDir/network/build/reports/detekt"
}
}
And here is what I'm trying for the custom gradle task:
task detektAll {
group = 'verification'
dependsOn 'detektCheck'
doLast {
println "\n##################################################" +
"\n# Detekt'ed all the things! Go you! #" +
"\n##################################################"
}
}
I need to add -Ddetekt.profile=app and the others for each profile.
How can I accomplish this?

Suppress Gradle's JavaExec output

I have gradle code below and I don't know how to avoid huge output generated by JavaExec task. I haven't found any option of JavaExec for it. If anyone knows better way of ignoring it, please share it.
def getStubOutput() {
return new FileOutputStream(new File("${buildDir}/temp"))
}
configure(project(':jradius:dictionary-min')) {
evaluationDependsOn(':jradius')
sourceSets {
main {
java {
srcDir "${projectDir}/target/dictionary-src"
}
}
}
dependencies {
compile project(':jradius:core')
}
task genSources(type: JavaExec) {
main = 'net.jradius.freeradius.RadiusDictionary'
classpath configurations.all
args = ["net.jradius.dictionary", "${projectDir}/../freeradius/dict-min", "${projectDir}/target/dictionary-src"]
maxHeapSize = "800m"
standardOutput = getStubOutput()
}
jar {
archiveName = "jradius-dictionary-min-1.1.5-SNAPSHOT.jar"
}
genSources.dependsOn ':jradius:cloneJradius'
compileJava.dependsOn genSources
}
I simply use a dummy OutputStream that does nothing in its write method:
def dummyOutputStream = new OutputStream() {
#Override
public void write(int b) {}
}
exec {
executable = name
standardOutput = dummyOutputStream
errorOutput = dummyOutputStream
ignoreExitValue = true
}
A great solution I came across is to modify the logging level of the task. If you set it to INFO, then it will squelch all the output of that task, unless gradle is run with --info.
Alternatively, you can set the level to LogLevel.QUIET, which will completely silence it.
task chatty(type: Exec) {
....
logging.captureStandardOutput LogLevel.INFO
}
As in the comment I thought that standardOutput can be set to null but the following piece of code (taken from: org.gradle.process.internal.AbstractExecHandleBuilder) shows that's not possible:
public AbstractExecHandleBuilder setStandardOutput(OutputStream outputStream) {
if (outputStream == null) {
throw new IllegalArgumentException("outputStream == null!");
}
this.standardOutput = outputStream;
return this;
}
What You can do is to redirect the output to temporary file (file will be deleted!) with this oneliner:
task genSources(type: JavaExec) {
main = 'net.jradius.freeradius.RadiusDictionary'
classpath configurations.all
args = ["net.jradius.dictionary", "${projectDir}/../freeradius/dict-min", "${projectDir}/target/dictionary-src"]
maxHeapSize = "800m"
standardOutput = { def f = File.createTempFile('aaa', 'bbb' ); f.deleteOnExit(); f.newOutputStream() }()
}
or if You'd like to save this output for further reading:
task genSources(type: JavaExec) {
main = 'net.jradius.freeradius.RadiusDictionary'
classpath configurations.all
args = ["net.jradius.dictionary", "${projectDir}/../freeradius/dict-min", "${projectDir}/target/dictionary-src"]
maxHeapSize = "800m"
standardOutput = new File(project.buildDir, 'radius.log').newOutputStream()
}
The last option is to add apache commons-io to script dependencies and set standardOutput to NullOutputStream. In can be done as follows:
import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'commons-io:commons-io:2.4'
}
}
task genSources(type: JavaExec) {
main = 'net.jradius.freeradius.RadiusDictionary'
classpath configurations.all
args = ["net.jradius.dictionary", "${projectDir}/../freeradius/dict-min", "${projectDir}/target/dictionary-src"]
maxHeapSize = "800m"
standardOutput = NULL_OUTPUT_STREAM
}
That's all that comes to my head.
This disables the standard output from a javaExec task:
task myCustomTask(type: javaExec) {
standardOutput = new ByteArrayOutputStream()
classpath = ...
main = ...
args ....
}

Resources