Gradle build changes the way my app parses the command line


#1

I’m having a bit of a weird problem, and I haven’t had any success researching why this is happening. I have a command line application, and if I build the JAR with IntelliJ, running the JAR gets me the arg parsing I would expect, but building the JAR with Gradle does not.

To illustrate, if my main func is

fun main(args: Array<String>) = args.forEach(::println)

And I run
java -jar "Mary had a little lamb"

the output will be
Mary had a little lamb

But if I build the same code with Gradle and do the same thing, I get

Mary
had
a
little
lamb

In other words, it looks like when I build with Gradle, the runtime’s command line parser is splitting the arguments on whitespace and passing each word as a separate array element, even though they are enclosed in quotes on the command line.

I don’t even know how this is possible, and googling hasn’t turned up anything useful (the amount of noise when you search for things like Java command line doesn’t help). Anyone have any kind of idea where I can start looking for a way to fix this behavior?


#2

What plugin do you use to build jar with gradle? Also have you tried to see the contents of the jar?


#3

Are you sure it’s because of Gradle? To me, the difference just looks like calling

java -jar "Mary had a little lamb"
vs.
java -jar Mary had a little lamb


#5

Looks like I’m not using a plugin at all:

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
    }

    manifest {
        attributes 'Main-Class': 'org.tkeating.gi.MainKt'
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}

Not sure WHY I did it this way… this dates way back to when I first started using Gradle. This seems pretty hacky to me now.

I have, although only a bit. The files seemed the same, but this is probably something I should look into more closely.

Pretty sure. I tested it very carefully, as this is an issue I’ve been working around since I started this project quite some time ago. It’s only recently that I realized this is not standard JVM behavior.


#6

Can you please show how how you launch the jar file in both cases? Your original statement java -jar "Mary had a little lamb" is clearly incorrect as you’re missing at least the jar file name.

Maybe upload both jar files somewhere.


#7

So I actually figured this out, and it turns out it’s the dumbest and most obvious possible thing.

The answer is, when I was testing my gradle build (my usual build), I wasn’t invoking it directly; I have a bash script in a directory that is on my PATH, which is what I was using. And the command line in the script looked like:

java -jar path/to/my/jar.jar $*

Literally two minutes of googling made it clear that it was the $* that was at fault. Changed it to "$@" and all was well.

:man_facepalming:t2: :man_facepalming:t2: :man_facepalming:t2:

Thanks everybody for coaxing me to recheck things, which quickly turned up the solution.