Gradle start scripts env - gradle

In gradle run task I have info about lib path:
run {
systemProperty "java.library.path", "lib/native"
}
Is it possible to add the same variable to some gradle task that will include variable to the bin scripts, for now I have to put them manualy but I would like to automate this with gradle:
CLASSPATH=$APP_HOME/lib/***.jar:$APP_HOME/lib/***.jar: ...
>>> LD_LIBRARY_PATH=$APP_HOME/lib

You can use some text, such as MY_APP_HOME, to define java.library.path in JVM arguments:
applicationDefaultJvmArgs = ['-Djava.library.path=MY_APP_HOMElib/native']
And then substitute it by start scripts APP_HOME variable in each script:
startScripts {
doLast {
unixScript.text = unixScript.text.replace('MY_APP_HOME', '\$APP_HOME/')
windowsScript.text = windowsScript.text.replace('MY_APP_HOME', '%APP_HOME%\\')
}
}

Related

Run gradle task multiple times

I have a gradle project containing two modules in subdirectories. The directory structure is as below.
root
module1
build.gradle
module2
build.gradle
build.gradle
settings.gradle
The top level settings.gradle includes the two modules. The top level build.gradle contains the following.
task runScript(type: Exec) {
workingDir 'scripts'
commandLine 'python3', 'myscript.py'
}
project(':module1') {
evaluationDependsOn(':module1')
final test = tasks.findByName('test')
test.dependsOn(runScript)
}
project(':module2') {
evaluationDependsOn(':module2')
final test = tasks.findByName('test')
test.dependsOn(runScript)
}
Task runScript sets the database to a known state and must be run before each module test task.
When I run the test task my script only executes once. How can I ensure it executes multiple times?
$ ./gradlew test
... some output
:runScript
RUNNING MY SCRIPT
:module1:test
RUNNING MODULE1 TESTS
... some output
:module2:test
RUNNING MODULE2 TESTS
Things I Tried
I tried adding outputs.upToDateWhen {false} to the task runScript so Gradle never thinks it is up to date. This didn't make any difference; I assume because the task still only occurs once in the task graph?
I tried replacing the lines containing dependsOn for each module with test.doFirst {runScript.execute()}. This changes when the task gets executed but does not result in multiple executions.
$ ./gradlew test
... some output
:module1:test
RUNNING MY SCRIPT
RUNNING MODULE1 TESTS
... some output
:module2:test
RUNNING MODULE2 TESTS
I tried creating a new task for each module. This works but it's duplicating code.
project(':module1') {
evaluationDependsOn(':module1')
final test = tasks.findByName('test')
task runScript(type: Exec) {
workingDir '../scripts'
commandLine 'python3', 'myscript.py'
}
test.dependsOn(runScript)
}
project(':module2') {
evaluationDependsOn(':module2')
final test = tasks.findByName('test')
task runScript(type: Exec) {
workingDir '../scripts'
commandLine 'python3', 'myscript.py'
}
test.dependsOn(runScript)
}
If your script is necessary for each run of each Test task, simply assure its execution before each Test task. Why even use a task then?
subprojects {
tasks.withType(Test) {
doFirst {
exec {
workingDir 'scripts'
commandLine 'python3', 'myscript.py'
}
}
}
}

How to apply javaagent to gretty plugin based on gradle command line?

The question is specific, but it's more of a general 'how to do this in gradle' question.
I have a demo java web app that I can run using the gretty plugin. I would like to selectively control whether a javaagent is applied to the jvmArgs of the gretty process based on a command line flag. The agent jar location is known by getting its path from a dummy configuration:
configurations {
agent
}
dependencies {
...
agent group: 'com.foo', name: 'foo-agent', version: '1.0'
}
I know I can access the jar file location using something like:
project.configurations.agent.find { it.name.startsWith("foo-agent") }
How can I selectively apply that to the gretty jvmArgs configuration based on a command line property such as
gradle -PenableAgent
I ended up solving this by creating a task and simply calling it before I run the war:
task agent {
doFirst {
def agentJar = project.configurations.agent.find { it.name.startsWith("foo-agent") }
gretty.jvmArgs << "-javaagent:" + agentJar
}
}
Then I can simply call:
gradle agent appRunWar
In my project I use Spring Instrument as java agent so this was my solution.
You can make appRun task dependent on agent task then no additional gradle run parameter needed.
dependencies {
...
agent 'org.springframework:spring-instrument:4.2.4.RELEASE'
}
configurations {
dev
agent
}
gretty {
...
contextPath = '/'
jvmArgs=[]
springBoot = true
...
}
task agent {
doFirst {
def agentJar = project.configurations.agent.find{it.name.contains("spring-instrument") }
gretty.jvmArgs << "-javaagent:" + agentJar
}
}
project.afterEvaluate {
tasks.appRun.dependsOn agent
}

Gradle not able to access system environmental properties

I have this script in build.gradle and i am unable to access tomcat home from system environmental variables. (FYI - null value) I verified i have environmental variable as TOMCAT_HOME = "C:\tomcatC:\apache-tomcat-8.0.21"
Any ideas what i might be doing wrong ?
build.mustRunAfter clean
task deploy(dependsOn: ['clean', 'build', 'deployWar']) << {
println '*********************'
println 'hcadmin.war installed'
println '*********************'
}
task deployWar(type: Copy) {
from war
into System.getProperty("TOMCAT_HOME") + "//webapps"
}
You're basically mixing up java system properties with environment variables:
To get environment variables:
System.getenv()["TOMCAT_HOME"] // Java-style
System.env.'TOMCAT_HOME' // Groovy-style
To get java system properties variables (eg with 'java.home' property):
System.getProperty("java.home") // Java-style
System.getProperties()["java.home"] // Java-style
System.properties.'java.home' // Groovy-style
Try Groovy way System.env.'TOMCAT_HOME'

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'
}

Resources