Passing Command Line Arguments to a Spring Boot Application via a bootRun Task in Gradle

There currently seems to be no easy way to pass arguments to a Spring Boot application launched using the bootRun task in Gradle. There are plenty of stack overflow questions asking about this and at least one active issue for Spring Boot:

I ran into this while working on a small utility application for a previous client. In order to support the conversion of a number of mainframe applications to web applications, they needed to add LDAP network ids to an “operator” authorization DB2 table containing mainframe user ids that was used by existing stored procedures and some of the converted applications. The utility application read in an excel export of the network users and matched up records to the mainframe users, creating an entry for the ldap id with the same authorization privileges.

While developing this utility application I became frustrated that I did not have a good way to pass in the excel workbook location and worksheet name to the application the same way when running it as either an executable jar or via a bootRun task. I did not enjoy having to rebuild the jar to test changes to the application and did not want to pass that information via system properties or to hard code those values in for development (as I did not trust myself to always remember to remove them before committing changes).

In the application I was using a SimpleCommandLinePropertySource to pull out the arguments.

static void main(String[] args) {
    PropertySource propertySource = new SimpleCommandLinePropertySource(args)" ${}")
    List commandLineArgs = propertySource.getNonOptionArgs()
    String excelFilePath = commandLineArgs?.first()
    String workSheetName = commandLineArgs?.last()

This worked fine when I built the executable jar and ran it like the following:

java -jar ./build/libs/SpringBootArgsExample.jar ./src/test/resources/testData.xlsx sheet1

But I was not able to pass the arguments when I used bootRun or any of the custom bootRun tasks I had extended to set the profile to the correct environment: dev, test, prod.

After some research, I came to the solution of creating a task execution listener that would collect any arguments from the task’s project and pass them on to the task being called as long as the task was a

class BootRunPropertyListener implements TaskExecutionListener {
    void afterExecute(Task t, TaskState s) {}
    void beforeExecute(Task t) {
        if (t instanceof {
            if (t.project.hasProperty('args')) {
                String arguments =['args']
                Collection args = arguments.split('\\s+')
                t.args = args

I then added that listener to the project and created custom tasks that extended

project.gradle.addListener(new BootRunPropertyListener())
task bootRunH2(type: {
    doFirst() {
        main = project.mainClassName
        classpath = sourceSets.main.runtimeClasspath
        systemProperty "", "H2"
task bootRunDev(type: {
    doFirst() {
        main = project.mainClassName
        classpath = sourceSets.main.runtimeClasspath
        systemProperty "", "Dev"

This allowed me to run my different tasks and easily pass in the desired arguments using -Pargs:

gradlew bootRunH2 -Pargs="./src/test/resources/testData.xlsx sheet1"

I know this is only one of many ways to solve this issue, but hopefully it saves someone some time trying to figure out a way to solve it.

I have posted a small example application of the solution to github.

About the Author

Rob Boler profile.

Rob Boler

Sr. Consultant

Rob has always been interested in computers, and remembers first attempting programming a hangman game on an Apple IIE in grade school. He has over 15 years of software development experience using Java / Spring, primarily in the transportation and defense industries. He prides himself as being able to solve complex software problems, while also being able to lead small teams of developers. Rob has a wide range of project experience ranging from dynamic web applications to high volume message processing, to applying Big Data technologies for data pattern analysis.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
React Server Components
The React Team recently announced new work they are doing on React Server Components, a new way of rendering React components. The goal is to create smaller bundle sizes, speed up render time, and prevent […]
Jolt custom java transform
Jolt is a JSON to JSON transformation library where the transform is defined in JSON. It’s really good at reorganizing the json data and massaging it into the output JSON you need. Sometimes, you just […]
Page Object Model for UI Testing
How to make a multi-handled range input
The HTML range input is a great way to allow your users to manipulate a numeric value using their mouse. The range input that is currently provided by browsers only supports a single handle, which […]