borrowed this shamely from here
Process process = new ProcessBuilder("C:\\PathToExe\\MyExe.exe","param1","param2").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
More information here
Other issues on how to pass commands here and here
Answer from Steven on Stack Overflowborrowed this shamely from here
Process process = new ProcessBuilder("C:\\PathToExe\\MyExe.exe","param1","param2").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
More information here
Other issues on how to pass commands here and here
You might also try its more modern cousin, ProcessBuilder:
Java Runtime.getRuntime().exec() alternatives
Use a p = new ProcessBuilder(params).start(); instead of
p = Runtime.getRuntime().exec(params);
Other than that looks fine.
Perhaps you should use waitFor() to obtain the result code. This means that the dump of the standard output must be done in another thread:
String path;
String[] params = new String [3];
params[0] = "D:\\prog.exe";
params[1] = picA+".jpg";
params[2] = picB+".jpg";
try {
final Process p = Runtime.getRuntime().exec(params);
Thread thread = new Thread() {
public void run() {
String line;
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null)
System.out.println(line);
input.close();
} catch (IOException e) {System.out.println(" procccess not read"+e);}
};
thread.start();
int result = p.waitFor();
thread.join();
if (result != 0) {
System.out.println("Process failed with status: " + result);
}
javafx - How Can I execute external program with arguments in Java ...
exec - Executing an external program in Java with arguments - Stack Overflow
java - Call an executable and pass parameters - Stack Overflow
Need to pass Java argument at runtime on client side
There is a exec method specifically overloaded for your purposes. It takes as an argument String array which holds the command and the arguments for the command. That seems to be exactly what you need. Please look at the API
I think you are confusing about the exe arguments. Try this one:
private String appDomain = Paths.get("").toAbsolutePath().normalize().toString();
private String exepath = appDomain + "\\src\\bin\\exeResources\\MyExe.exe";
private String exeargs = "silent-load";
try {
Runtime r = Runtime.getRuntime();
r.exec(exepath + " " + exeargs);
} catch (IOException e) {
e.printStackTrace();
}
Pass your arguments in constructor itself.
Process process = new ProcessBuilder("C:\\PathToExe\\MyExe.exe","param1","param2").start();
You're on the right track. The two constructors accept arguments, or you can specify them post-construction with ProcessBuilder#command(java.util.List) and ProcessBuilder#command(String...).
I have a application which was previously using JNLP for downloading jars I replaced this JNLP with a fatjar. Everything works fine until Java 15 but due to reflective access issue I am unable to run this fatjar in java 17 and above I found a fix for this but it involves passing an argument at runtime. Now this fatjar is downloaded at client's machine and he won't run this fatjar with cmd line he would just double click it and the fatjar would run but without those jvm argument. Is there any way to embedd this jvm argument in that fatjar such that it runs successfully on double click.
P.S. : I am new to software industry. Only 3 months in experience. Thanks.
This is normal: you are attempting to launch a command normally issued by a shell.
Here, <proof.in and >proof.out are taken as literal arguments to the otter executable, and not shell redirections. But seeing the home page for this tool, it will not work: it expects data on stdin, which the redirect normally provides.
You need to launch this command via a shell, and preferably using a process builder:
final ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "otter <proof.in >proof.out");
final Process p = pb.start();
etc etc.
You should also ensure, of course, that the program runs from the correct directory -- fortunately, ProcessBuilder also allows you to do that.
Here is a link to another question with a very detailed answer on how to do this correctly in an async way with threads. This is the only way to not block your main thread and hang your GUI.
private class ProcessResultReader extends Thread
{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
{
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try
{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
then you use the above class like so
try
{
final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0)
{
System.out.print(stdout.toString());
}
else
{
System.err.print(stderr.toString());
}
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
throw new RuntimeException(e);
}