In short, for the answer, add -jar
right before the JAR file name.
The accepted answer is not 100% correct for several reasons: it does not recognize whitespace-delimited and whitespace-containing arguments, and may mess up with quote characters that must be passed (therefore properly escaped) to the delegated Java app. In short, do not use Arguments
if the string is not known to be a constant (having spaces will require manual escaping anyway), but merely prefer ArgumentList
that handles each argument properly.
Here is an example Java application to deal with command line arguments:
public final class SayHello {
private SayHello() {}
public static void main(final String... names) {
for ( final String name : names ) {
System.out.printf("hello %s!\n", name);
}
}
}
The manifest for the JAR file:
Manifest-Version: 1.0
Main-Class: SayHello
Making a JAR file out of it is simple:
javac SayHello.java
jar cfm SayHello.jar MANIFEST.MF SayHello.class
Example of use:
java -jar SayHello.jar 'John Doe' Anonymous
that gives:
hello John Doe!
hello Anonymous!
Now, an example C# program that passes the -jar
argument to the java
process so that it recognizes the given file as a JAR file and demonstrates what can go wrong with Arguments
if passed as a string.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
using System.Diagnostics;
public static class SayHello {
public static void Main() {
// interprets 3 names: John, Doe, Anonymous (wrong)
RunJavaJarBadly1("SayHello.jar", "John Doe Anonymous");
// interprets 1 name: John Doe Anonymous (wrong)
RunJavaJarBadly2("SayHello.jar", "John Doe Anonymous");
// interprets 2 names: John Doe, Anonymous (correct, but bad: requires the first name to be quoted at the call-site)
RunJavaJarBadly1("SayHello.jar", "\"John Doe\" Anonymous");
// interprets 1 name: "John Doe" Anonymous (wrong: interprets everything as a single name)
RunJavaJarBadly2("SayHello.jar", "\"John Doe\" Anonymous");
// interprets 2 names, no ambiguous call, each name is recognized properly, does not require quoting at the call site
RunJavaJar("SayHello.jar", "John Doe", "Anonymous");
}
private static void RunJavaJarBadly1(string jarPath, string argumentsFortheJarFile) {
var process = new Process();
process.StartInfo.FileName = "java";
process.StartInfo.Arguments = @"-jar "+ jarPath +" " + argumentsFortheJarFile;
process.Start();
process.WaitForExit();
}
private static void RunJavaJarBadly2(string jarPath, string jarArgs) {
var process = new Process();
process.StartInfo = new ProcessStartInfo("java") {
ArgumentList = { "-jar", jarPath, jarArgs }
};
process.Start();
process.WaitForExit();
}
private static void RunJavaJar(string jarPath, params string[] jarArgs) {
var process = new Process();
process.StartInfo = new ProcessStartInfo("java") {
ArgumentList = { "-jar", jarPath }
};
foreach ( var jarArg in jarArgs ) {
process.StartInfo.ArgumentList.Add(jarArg);
}
process.Start();
process.WaitForExit();
}
}
The code above produces (no legend in the output, but added for explanation):
hello John! \_ #1/1: incorrect, the space is ignored
hello Doe! /
hello Anonymous! -- #1/2: correct, no spaces in-between
hello John Doe Anonymous! -- #2/1|2: incorrect
hello John Doe! -- #3/1: correct, but requires the call site to escape the argument
hello Anonymous! -- #3/2: correct, no need to escape, thanks to no spaces
hello "John Doe" Anonymous! -- #4/1|2: incorrect, similar to #2/1|2
hello John Doe! -- #5/1: correct, let the framework do its job
hello Anonymous! -- #5/2: correct, let the framework do its job