Gradle task - pass arguments to Java application
Asked Answered
M

10

160

I have a Java application that runs with a custom gradle task and the application requires some arguments upon being invoked. These are:

programName ( string | -f filename | -d key | -h)
Options:
    string         Message to be used.
    -d key         Use default messages, key must be s[hort], m[edium] or l[ong].
    -f filename    Use specified file as input.
    -h             Help dialog.

Gradle task looks like:

task run (type: JavaExec){
    description = "Secure algorythm testing"
    main = 'main.Test'
    classpath = sourceSets.main.runtimeClasspath
}

I've tried running gradle run -h and it does not work.

Multicellular answered 22/12, 2014 at 14:6 Comment(3)
Did the answers fit your needs? If so, you should mark one as solution.Whittington
Not really... a friend and I discovered a way to do it but we don't have it clear yet so as to publish a solution, both proposed solutions were tried, we understood what it'd to be done, but didn't really seem to work...Multicellular
@6uitar6reat6od How did you resolve it in the end? Also what version of gradle?Dibromide
B
110

Since Gradle 4.9, the command line arguments can be passed with --args. For example, if you want to launch the application with command line arguments foo --bar, you can use

gradle run --args='foo --bar'

See Also Gradle Application Plugin

How to upgrade Gradle wrapper

Bathhouse answered 18/7, 2018 at 17:36 Comment(7)
Is the ' expected or a typo? Should all arguments be passed as a string delimited by single quotes?Multicellular
@Multicellular Fixed per docs.gradle.org/current/userguide/…Rissole
gradle run --args='foo --bar'Felspar
'foo --bar' is confusing, why not just use 'foo bar'.Allveta
@EricWang These are arbitrary command line arguments a program may need. It's nice to show that gradle supports any kind of arguments, since the raw string is passed to the built application.Annunciata
If you have args defined in your run block, per Claudio's answer below, then they will all be overridden by your --args flag. In other words, gradle doesn't try to merge the two.Ancestry
If you face issues with gradle run --args='foo --bar', use " " quotation marks instead of ' '. For instance : gradle run --args="arg1 arg2".Phonsa
D
132

Gradle 4.9+

gradle run --args='arg1 arg2'

This assumes your build.gradle is configured with the Application plugin. Your build.gradle should look similar to this:

plugins {
  // Implicitly applies Java plugin
  id: 'application'
}

application {
  // URI of your main class/application's entry point (required)
  mainClassName = 'org.gradle.sample.Main'
}

Pre-Gradle 4.9

Include the following in your build.gradle:

run {
    if (project.hasProperty("appArgs")) {
        args Eval.me(appArgs)
    }
}

Then to run: gradle run -PappArgs="['arg1', 'args2']"

Dibromide answered 1/4, 2015 at 4:3 Comment(0)
B
110

Since Gradle 4.9, the command line arguments can be passed with --args. For example, if you want to launch the application with command line arguments foo --bar, you can use

gradle run --args='foo --bar'

See Also Gradle Application Plugin

How to upgrade Gradle wrapper

Bathhouse answered 18/7, 2018 at 17:36 Comment(7)
Is the ' expected or a typo? Should all arguments be passed as a string delimited by single quotes?Multicellular
@Multicellular Fixed per docs.gradle.org/current/userguide/…Rissole
gradle run --args='foo --bar'Felspar
'foo --bar' is confusing, why not just use 'foo bar'.Allveta
@EricWang These are arbitrary command line arguments a program may need. It's nice to show that gradle supports any kind of arguments, since the raw string is passed to the built application.Annunciata
If you have args defined in your run block, per Claudio's answer below, then they will all be overridden by your --args flag. In other words, gradle doesn't try to merge the two.Ancestry
If you face issues with gradle run --args='foo --bar', use " " quotation marks instead of ' '. For instance : gradle run --args="arg1 arg2".Phonsa
C
39

If you want to use the same set of arguments all the time, the following is all you need.

run {
    args = ["--myarg1", "--myarg2"]
}
Cyton answered 23/4, 2017 at 2:54 Comment(3)
Ok, for absolute beginners like me : in order to be able to define run task your build.gradle should contain following two lines: apply plugin:'application' mainClassName="<full classname including the package path>" Otherwise, you cannot define the run method in the buuild.gradleSelda
I'm using the id 'application' plugin and this was the answer I needed (it works).Mackoff
I am getting "unresolved reference: args". Gradle 7.3.Pithos
M
29

Sorry for answering so late.

I figured an answer alike to @xlm 's:

task run (type: JavaExec, dependsOn: classes){
    if(project.hasProperty('myargs')){
        args(myargs.split(','))
    }
    description = "Secure algorythm testing"
    main = "main.Test"
    classpath = sourceSets.main.runtimeClasspath
}

And invoke like:

gradle run -Pmyargs=-d,s
Multicellular answered 1/4, 2015 at 15:41 Comment(0)
W
7

You can find the solution in Problems passing system properties and parameters when running Java class via Gradle . Both involve the use of the args property

Also you should read the difference between passing with -D or with -P that is explained in the Gradle documentation

Whittington answered 22/12, 2014 at 14:21 Comment(1)
Saw this too. Still looking. All of these methods seem to want to edit/massage the current properties and pass them along. Command line and Java properties for running an application or service are akin to "Context" or "Configuration" setting. It would be better to have a plug-in that does things like "run parameters" as a side-by-side profiles or something.Inga
E
6

Of course the answers above all do the job, but still i would like to use something like

gradle run path1 path2

well this can't be done, but what if we can:

gralde run --- path1 path2

If you think it is more elegant, then you can do it, the trick is to process the command line and modify it before gradle does, this can be done by using init scripts

The init script below:

  1. Process the command line and remove --- and all other arguments following '---'
  2. Add property 'appArgs' to gradle.ext

So in your run task (or JavaExec, Exec) you can:

if (project.gradle.hasProperty("appArgs")) {
                List<String> appArgs = project.gradle.appArgs;

                args appArgs

 }

The init script is:

import org.gradle.api.invocation.Gradle

Gradle aGradle = gradle

StartParameter startParameter = aGradle.startParameter

List tasks = startParameter.getTaskRequests();

List<String> appArgs = new ArrayList<>()

tasks.forEach {
   List<String> args = it.getArgs();


   Iterator<String> argsI = args.iterator();

   while (argsI.hasNext()) {

      String arg = argsI.next();

      // remove '---' and all that follow
      if (arg == "---") {
         argsI.remove();

         while (argsI.hasNext()) {

            arg = argsI.next();

            // and add it to appArgs
            appArgs.add(arg);

            argsI.remove();

        }
    }
}

}


   aGradle.ext.appArgs = appArgs

Limitations:

  1. I was forced to use '---' and not '--'
  2. You have to add some global init script

If you don't like global init script, you can specify it in command line

gradle -I init.gradle run --- f:/temp/x.xml

Or better add an alias to your shell:

gradleapp run --- f:/temp/x.xml
Ectopia answered 22/8, 2017 at 8:3 Comment(1)
This works great ... if none of my arguments start with a dash. This makes it useless for common command line parsers :(. As soon as that happens, gradle seems to treat that arg as an argument to gradle (I don't think the argsI.remove() is having the desired effect). Suggestions?Sadirah
T
4

You need to pass them as args to the task using project properties, something like:

args = [project.property('h')]

added to your task definition (see the dsl docs)

Then you can run it as:

gradle -Ph run
Tollmann answered 22/12, 2014 at 14:19 Comment(0)
L
0

Using Kotlin DSL:

plugins {
    java
    application
}

application {
    mainClass = "io.fouad.AppLauncher"
    applicationDefaultJvmArgs = listOf("-Dsome.system.properties=123")
}

tasks.withType(JavaExec::class) {
    args = listOf("abc", "def")
}
Lockridge answered 24/9, 2023 at 7:10 Comment(1)
Specifying the java plugin here is redundant, see: docs.gradle.org/current/userguide/application_plugin.htmlFolkways
O
0

Building on Eng.Fouad's answer, with Kotlin DSL and application plugin, use something like below, to pass arguments to only the run task added by the application plugin, instead of to all the tasks of type JavaExec:

plugins {
    application
}

application {
    mainClass.set("main.Test")
}

tasks.run<JavaExec> {
    args(listOf("-h"))
}
Outburst answered 22/1 at 20:3 Comment(0)
S
0

Here is what I found when I was trying to pass Spring Boot JPA parameters into an application that I was launching from the command line. (I'm using Gradle 7.6.1)

First, in your build.gradle file:

if (project.hasProperty("args")) {
    ext.cmdargs = project.getProperty("args")
} else { 
    ext.cmdargs = ""
}

Then, also in your build.gradle file:

task runDemo(dependsOn: 'jar') {
    doLast {
        javaexec {
            classpath = sourceSets.main.runtimeClasspath
            jvmArgs = [ "-Xmx8G" ]
            mainClass = "my.demo.app.App"
            args cmdargs.split()
        }

    }
}

Then, to run "runDemo" on a bash command line, you do the following:

$ ./gradlew runDemo -Pargs='arg1 -arg2 --arg3 
--spring.datasource.username=myusername
--spring.datasource.password=mypassword
--spring.datasource.driver-class-name=some.sql.Driver'

Some notes:

  1. -P creates a property, args in this case, that is passed to gradle.
  2. The args property value is enclosed in single quotes.
  3. Because I'm using bash and my args property value spanned multiple lines, I didn't have to do anything special because of how bash interprets text contained within single quotes. Specifically, you do not need a backslash on the end of each line to continue on the next line within the text bounded by single quotes.
  4. The build.gradle file reads the args property and puts the value in ext.cmdargs. Then, the runDemo task calls cmdargs.split() and puts the resulting array into the args variable that is passed into you application.
Sarah answered 15/2 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.