In gradle, what is the difference betweeen javaexec and a JavaExec task? - gradle

For example, I can have a JavaExec task:
task javaExecCaseA(type: JavaExec) {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(11)
}
classpath = files("MySimpleProgram.jar")
}
or, inside a generic task:
task javaExecCaseB {
doLast {
javaexec {
classpath = files("MySimpleProgram.jar")
}
}
}
I haven't figured out how to specify the JavaLanguageVersion in the 2nd case (javaExecCaseB).
The bigger question though, is what is the difference?
I've tried various ways to set the version in javaExecCaseB, but I end up with an error like:
Could not set unknown property 'javaLauncher' for object of type org.gradle.process.internal.DefaultJavaExecAction_Decorated

I have found that the task is the gradle "JavaExec" task.
And the 2nd case, javaexec is a Project method.
I began this quest to find a way to run Java programs using a different JVM than gradle itself is using (set from an environment variable or command line when running gradle).
I was able to get it to work in both cases:
ext {
MyJvmVersion = 11
}
task SampleJavaExec1(type: JavaExec) {
// Example task for using a custom JVM version with a JavaExec task
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(MyJvmVersion as int)
}
environment['JAVA_HOME'] = javaLauncher.get().metadata.installationPath.asFile.absolutePath
classpath = files("MySimpleProgram.jar")
}
task SampleJavaExec2 {
// Example task for using a custom JVM version with the javaexec method
doLast {
javaexec {
environment['JAVA_HOME'] = "C:\\Program Files\\AdoptOpenJDK\\jdk-11.0.10.9-hotspot"
executable = "C:\\Program Files\\AdoptOpenJDK\\jdk-11.0.10.9-hotspot\\bin\\java.exe"
classpath = files("MySimpleProgram.jar")
}
}
}
In the 2nd case, javaexec() doesn't appear to have a "javaLauncher".
Instead of hardcoding a path, I also found that I can use javaLauncher to find it for me by adding this code inside the javaexec{} block:
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(MyJvmVersion as int)
}
environment['JAVA_HOME'] = javaLauncher.get().metadata.installationPath.asFile.absolutePath
This should invoke the auto download JVM resolution as well, but I've not tested that part.

Related

How to pass text parameters into a Gradle task from another gradle task (not command line)

I'm wondering how I can pass a parameter (PARAM) to a Gradle task from another Gradle task that depends on it.
For example something along these lines
task buildDist(PARAM) {
copy {
from "$projectDir/src/{PARAM}/ClientBanner.json"
into "$buildDir/${project.name}/"
}
and call this Gradle task from another one like:
task dist(type: Zip) {
from "$buildDir"
include "${project.name}/**/*"
archiveFileName = project.name + '.zip'
destinationDirectory = layout.buildDir.dir('dist')
dependsOn('buildDist(PARAM)')
}
#Shapebuster
The Gradle build script is Groovy (or Kotlin) based and can be extended using the supported syntax of that language. So, in your example, you should be able to use the PARAM like so:
task buildDist(String param1) {
copy {
from "$projectDir/src/$param1/ClientBanner.json"
into "$buildDir/${project.name}/"
}
}
and then:
task dist(type: Zip) {
from "$buildDir"
include "${project.name}/**/*"
archiveFileName = project.name + '.zip'
destinationDirectory = layout.buildDir.dir('dist')
dependsOn buildDist("$param1")
}

Run executable jar with parameters from gradle

I wish to run executable jar from my gradle file. I have tied:
task runJar(dependsOn:jar) << {
javaexec {
main="-jar"; args "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
}
}
But I get "Could not find property 'jar' on project ':MyProj"
I also tried:
task runScheduleReader << {
javaexec {
main = "MainClass"
classpath = "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
args('1')
}
}
I am relatively new to groovy, can you please help me with that?
P.S... I put those function outside of android {}
In your first code snippet dependsOn in task declaration means, that task runJar should be executed only after the jar task. Exception you get, says, that your current project doesn't have such a task. So, if you really don't need to execute jar task just before, you can simply not declere this task dependency:
task runJar() << {
javaexec {
main="-jar"; args "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
}
}
Though, this is a little bit strange case, when you have to execute some jar without relative path, this solution should work.
The second snippet should pass the jar as the argument too, but this time, it should be an arguments array, something like this:
task runScheduleReader() << {
javaexec {
main="-jar";
args = [
"C:/Development/AndroidStudioProjects/AndroidDev/Test.jar",
"1"
]
}
}

How to run JBoss TattleTale from inside Gradle build

I am in love with JBoss TattleTale. Typically, in my Ant builds, I follow the docs to define the Tattletale tasks and then run them like so:
<taskdef name="report"
classname="org.jboss.tattletale.ant.ReportTask"
classpathref="tattletale.lib.path.id"/>
...
<tattletale:report source="${src.dir]" destination="${dest.dir}"/>
I am now converting my builds over to Gradle and am struggling to figure out how to get Tattletale running in Gradle. There doesn't appear to be a Gradle-Tattletale plugin, and I'm not experienced enough with Gradle to contribute one. But I also know that Gradle can run any Ant plugin and can also executing stuff from the system shell; I'm just not sure how to do this in Gradle because there aren't any docs on this (yet).
So I ask: How do I run the Tattletale ReportTask from inside a Gradle build?
Update
Here is what the Gradle/Ant docs show as an example:
task loadfile << {
def files = file('../antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}
However, no where in here do I see how/where to customize this for Tattletale and its ReportTask.
The following is adapted from https://github.com/roguePanda/tycho-gen/blob/master/build.gradle
It bypasses ant and directly invokes the Tattletale Java class.
It was changed to process a WAR, and mandates a newer javassist in order to handle Java 8 features such as lambdas.
configurations {
tattletale
}
configurations.tattletale {
resolutionStrategy {
force 'org.javassist:javassist:3.20.0-GA'
}
}
dependencies {
// other dependencies here...
tattletale "org.jboss.tattletale:tattletale:1.2.0.Beta2"
}
task createTattletaleProperties {
ext.props = [reports:"*", enableDot:"true"]
ext.destFile = new File(buildDir, "tattletale.properties")
inputs.properties props
outputs.file destFile
doLast {
def properties = new Properties()
properties.putAll(props)
destFile.withOutputStream { os ->
properties.store(os, null)
}
}
}
task tattletale(type: JavaExec, dependsOn: [createTattletaleProperties, war]) {
ext.outputDir = new File(buildDir, "reports/tattletale")
outputs.dir outputDir
inputs.files configurations.runtime.files
inputs.file war.archivePath
doFirst {
outputDir.mkdirs()
}
main = "org.jboss.tattletale.Main"
classpath = configurations.tattletale
systemProperties "jboss-tattletale.properties": createTattletaleProperties.destFile
args([configurations.runtime.files, war.archivePath].flatten().join("#"))
args outputDir
}
The previous answers either are incomplete or excessively complicated. What I did was use the ant task from gradle which works fine. Let's assume your tattletale jars are beneath rootDir/tools/...
ant.taskdef(name: "tattleTaleTask", classname: "org.jboss.tattletale.ant.ReportTask", classpath: "${rootDir}/tools/tattletale-1.1.2.Final/tattletale-ant.jar:${rootDir}/tools/tattletale-1.1.2.Final/tattletale.jar:${rootDir}/tools/tattletale-1.1.2.Final/javassist.jar")
sources = "./src:./src2:./etcetera"
ant.tattleTaleTask(
source: sources,
destination: "tattleTaleReport",
classloader: "org.jboss.tattletale.reporting.classloader.NoopClassLoaderStructure",
profiles: "java5, java6",
reports: "*",
excludes: "notthisjar.jar,notthisjareither.jar,etcetera.jar"
){
}
So the above code will generate the report beneath ./tattleTaleReport. It's that simple. The annoyance is that the source variable only accepts directories so if there are jars present in those directories you do not wish to scan you need to add them to the excludes parameter.

Gradle javaexec task is ignoring jvmargs

I am trying to run my app using a Gradle javaexec task. However, jvmargs and args are not passed to the command execution. Why?
task runArgoDev(type: JavaExec) {
main = "org.app.ArgoDevRunner"
classpath = configurations.testRuntime
project.ext.jvmargs = ['-Xdock:name=Argo', '-Xmx512m', '-Dfile.encoding=UTF-8', '-Dapple.awt.textantialiasing=on', '-ea']
project.ext.args = ['-initParameter', 'implicit-scrollpane-support=true']
}
Above code doesn't have the desired effect because it sets extra properties on the project object, instead of configuring the task. Correct is jvmArgs = ... and args = .... (It's also possible to omit =, [, and ].)
Here is example, to pass program args and jvmargs to run task in gradle.
run {
args 'server', 'test.yml'
jvmArgs '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'
}

How to execute JavaExec multiple times in a single task using Gradle?

I have a task that runs a simple JavaExec.
What I cant seem to get working is the ability to run the JavaExec multiple times while iterating a Filetree object (containing the files) each of while I want to pass into the main JavaExec class one by one. Unfortunately the compiler or code generation tool as it is doesnot accept a directory as an arg so I need to pass the file as an arg per loop. Here's what I have:
task generateClasses(type: JavaExec) {
description = 'Generates Json Classes...'
classpath configurations.all
main = "org.apache.gora.compiler.Compiler"
FileTree tree = fileTree(dir: 'src/main')
tree.include '**/*.json'
tree.each {File file ->
println file
args = [ "src/main/json/$file.name", "$buildDir/generated-src/src/main/java" ]
}
}
compileJava.source generateClasses.outputs.files, sourceSets.main.java
From the above it works and I get all files listed but the JavaExec is called just the once on the very last file read.
How do I address the above? Please help.
How about using the project.javaexec method? See the API Documentation or the
DSL ref.
task generateClasses {
description = 'Generate Json Classes'
fileTree(dir: 'src/main', include:'**/*.json').each { file ->
doLast {
javaexec {
classpath configurations.all
main = 'org.apache.gora.compiler.Compiler'
args = ["src/main/json/$file.name", "$buildDir/generated-src/src/main/java"]
}
}
}
}

Resources