I am creating simple Java class and I would like to create out-of-the-box launcher by using gradle.
So I want to be able to run Java program via gradle:
gradlew clean run These are my command line arguments where These are my command line arguments are passed directly to my public static void main(String... args) method.
I am using the apply plugin: "application" which gives me the run task. But when I am running this 'as is' I've got:
* What went wrong:
Task 'These' not found in root project 'question1'. Some candidates are: 'test'.
Gradle interprets each argument not starting with a hyphen (-) as task name to define which tasks will be executed during the build. Since a task with the name These does not exist, the build fails.
You are using the Gradle Application Plugin, which, as you already stated, provides a run task. The docs show, that the run task is of the type JavaExec. So, to apply your arguments, add them to the run task via args:
run {
args 'These are my command line arguments'
}
To modify the arguments for each build without changing the build.gradle file, simply use project properties:
run {
args findProperty('runArgs')
}
And call gradle clean run -PrunArgs='These are my command line arguments'
Related
I have a Java project with Gradle.
Also I use Groovy to generate some class that will be used in Java code. Gradle executes script in separate task below:
task generateClass(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'generatorScript'
}
If I run this task, it first starts Java compilation, and only after that executes script. So if compilation failed, my generator script will not be executed. As it was mentioned, script generates one class, which my Java code is actually depends on, so, if not generated, Java will not be compiled. Vicious circle.
Script itself does not depend on some Java classes and is placed in separate sources directory:
/src
/main
/java
/...(java classes)
/groovy
generatorScript.groovy
It seems like nothing interferes me to execute script separately and independently from Java compilation.
How can I achieve that?
The problem is that you have the generator groovy script in the main sourcesets, and you try to compile this groovy script to use it as classpath for your JavaExec task. This is why compileJava task is executed, I guess.
You could do in another way, using groovy.ui.GroovyMain to execute your script, with following solution based on this link
configurations {
// a dedicated Configuration for Groovy classpath
groovyScript
}
dependencies {
// Set Groovy dependency so groovy.ui.GroovyMain can be found.
groovyScript localGroovy()
}
task generateClass(type: JavaExec) {
// Set class path used for running Groovy command line.
classpath = configurations.groovyScript
// Main class that runs the Groovy command line.
main = 'groovy.ui.GroovyMain'
// Pass your groovy script as argument of the GroovyMain main
// (can be improved)
args 'src/main/groovy/generatorScript.groovy'
}
I would like to pass JVM parameters to my Gradle test task. I use the parameters in a Cucumber feature file: ${app.url}. In the build.gradle file, I put those lines:
test {
testLogging.showStandardStreams = true
systemProperties System.getProperties()
}
When I execute gradle test -Dapp.url=http://....., I don't see the parameter was passed to the application. I also tried the below, but the result is the same:
test {
testLogging.showStandardStreams = true
systemProperty "app.url", System.getProperty("app.url")
}
When I use Maven and pass the same parameters as Jvm arguments, it works fine. Now I would like to switch to the Gradle, but I am stuck with passing parameters.
gradle is having -P or --project-prop option. Try this one and see.
-P, --project-prop Set project property for the build script
I have a multi-project dependency in my gradle build, but there's a feature that's somewhat in my way. Whenever I call a task name that exists in both projects, it calls them both. I don't like that.
My directory structure is as follows:
[Root]
---->[projA]
----------->build.gradle
---->[projB]
----------->build.gradle
So I have projB dependent on projA in my code.
Say I have a task run in projB:
task run << {
println 'projB running'
}
And I also have a task run in projA:
task run << {
println 'projA running'
}
By calling gradle run, I would get
:run
projB running
:projA:run
projA running
Is there any way to prevent some of the tasks from having this dependency? Some of them, say clean is fine, but I'd prefer to have specific tasks separate (without having to change the naming scheme).
The equivalent of what I want can be achieved by doing either:
gradle run -x :projA:run
or
gradle :run
I want a solution that is within the build file, though.
Thanks!
That fact that projB declares a project dependency on projA is irrelevant for the behavior you are seeing. If you execute a task from the root project of a multi-project build Gradle will try to find the task in any of its subprojects with the requested name and execute it. This feature is called task execution matching. Given this default behavior there's no way Gradle could know which run task you mean when executing gradle run from the root project. I'd suggest you define what you want to execute on the command line as mentioned in my previous comment.
If you really wanted to add logic to your build script, then you could achieve it with the following code:
def taskRequests = gradle.startParameter.taskRequests
def runTaskRequest = taskRequests.find { it.args.contains('run') }
if (runTaskRequest) {
gradle.startParameter.excludedTaskNames = [':projA:run']
}
The code provided would prevent the execution of the run task for the subproject projA if you execute the command gradle run. Keep in mind that it would also exclude :projA:run if you navigate to the projA subdirectory and run the same command. If you still want to be able to execute the run task from the subdirectory, then you'll have to build in additional logic.
Running a Java application built with Gradle requires adding to the classpath a directory for each individual library, as it stores them in individual directories.
Therefore, when you look at the command to launch the application in IntelliJ you can easily see a whole screen filled with classpath dependencies.
This is fine for IntelliJ because it can figure them out automatically, but I want to be able to run my command line tool in the terminal, writing arguments there instead of editing my run configuration each time I want to change anything. How can I do so without pasting a whole screen of machine-specific JAR dependencies from the IDE?
Is it possible to do it in a development environment without creating a giant JAR file bundling all the libraries?
Take a look at JavaExec task. You can create a custom task as such:
task customRun(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = "fully.qualified.name.of.your.main"
args = ["100", "1000" ...] // the command line options for your tool
jvmArgs = [ ... ] // additional JVM args you might need
}
Then you can invoke it using gradle customRun. If you want to be able to provide the command line arguments, I would suggest using gradle properties:
gradle -PcustomRunArgs="100 1000" customRun
and modifying the task to grab the arguments:
task ... {
...
if (project.hasProperty('customRunArgs')) {
args = customRunArgs.split(' ')
}
...
}
In my project, based on Gradle, i need parse command line and get option "-foo=...".
I try to use Getopt, but i can't understand some things:
I need to use LongOpt to read "-foo" from command line ?
How can i pass arguments to command line, with "gradle run" command ?
p.s. sorry for my bad english
gradle run is intended to launch an application without any arguments. You can hack around that if your arguments are pretty simple.
e.g.:
apply plugin: 'application'
run {
if (project.hasProperty("runArgs")) {
args project.runArgs.split()
}
}
Run it with gradle run -PrunArgs="arg1 arg2 arg3"
This is pretty cumbersome to type and if your arguments need to be escaped or have spaces, it's going to be harder to handle. At that point, I'd recommend just running gradle installApp and then the appropriate start script (build/install/<app>/bin/<app> arg1 arg2 arg3).
You can of course do something more elaborate: http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run
Use
gradle -q -Pfoo=bar printProps
in build.gradle
task printProps << {
println foo
}
output
bar
An example here