Is there a way around the java.lang.Process blocking the console?
In my case, when I execute the following code, my input is blocked in the console. So I can practically no longer enter anything. I've already tried a bit. For example, it doesn't work to start it in a new thread.
ProcessBuilder processBuilder = new ProcessBuilder(
"java",
"-Xms" + this.proxyConfiguration.getMemory() + "M",
"-Xmx" + this.proxyConfiguration.getMemory() + "M",
"-jar",
new File(path).getAbsoluteFile().getPath() + "//BungeeCord.jar");
processBuilder.directory(new File(path));
Process process = processBuilder.start();
Related
in Java 8, windows 10, i have a text app, i want to open a console and write something there,
first try is:
String [] cmd = {"cmd.exe", "/c", "start"};
ProcessBuilder f = new ProcessBuilder(cmd);
f.redirectErrorStream(true);
Process p = f.start();
PrintStream printStream=new PrintStream(p.getOutputStream());
//
System.setOut(printStream);
System.out.println("this write in CMD"); //did not work
second try is:
printStream.println("this write in CMD");//did not work
Can any body Help?
Launch conhost.exe instead, and write to the stdin of the retained Process, or if you redirect your output stream to the process writes with System.out will appear in the new console window:
String [] cmd = {"conhost.exe"};
ProcessBuilder f = new ProcessBuilder(cmd);
f.redirectErrorStream(true);
Process p = f.start();
PrintStream printStream=new PrintStream(p.getOutputStream());
System.setOut(printStream);
System.out.println("dir");
Hey all I am trying to change directories and then run my command with parameters.
final String path = "\\Local// Apps\\IBM\\SDP\\scmtools\\eclipse";
final String command = "scm help";
final String dosCommand = "cmd /c \"" + path + "\"" + command;
final Process process = Runtime.getRuntime().exec(dosCommand);
final InputStream in = process.getInputStream();
int ch;
while((ch = in.read()) != -1) {
System.out.print((char)ch);
}
It runs without errors but outputs nothing. However, this is what shows up after it finishes:
<terminated, exit value: 0>C:\Local Apps\IBM\SDP\jdk\bin\javaw.exe (Jul 22, 2019, 11:21:37 AM)
The expected output should be:
So am I doing this correctly?
AS suggested by Andreas
Process p = null;
ProcessBuilder pb = new ProcessBuilder("scm.exe");
pb.directory(new File("C:/Local Apps/IBM/SDP/scmtools/eclipse"));
p = pb.start();
I get the following error:
Cannot run program "scm.exe" (in directory "C:\Local Apps\IBM\SDP\scmtools\eclipse"): CreateProcess error=2, The system cannot find the file specified
You should use ProcessBuilder instead of Runtime.exec, e.g.
Process proc = new ProcessBuilder("scm.exe", "help")
.directory(new File("C:\\Local Apps\\IBM\\SDP\\scmtools\\eclipse"))
.inheritIO()
.start();
proc.waitFor(); // optional
You can also go through the command interpreter if needed, e.g. if the command is a script (.bat or .cmd file):
Process proc = new ProcessBuilder("cmd", "/c", "scm", "help")
.directory(new File("C:\\Local Apps\\IBM\\SDP\\scmtools\\eclipse"))
.inheritIO()
.start();
proc.waitFor();
The inheritIO() means that you don't need to process the commands output. It will be sent to the console, or wherever Java's own output would go.
In Java, I am trying to create a console program to execute Factorio, (note that there is no code that I can control or view there.) a game written in C++ with specific parameters. (That are calculated based on my input.) I can succesfully run it, but I want it's output stream to be redirected to my console output. I tried several methods:
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(executable.getParentFile());
builder.redirectOutput(Redirect.INHERIT);
Process fact = builder.start();
int result = fact.waitFor();
Gives no output
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(executable.getParentFile());
builder.inheritIO();
Process fact = builder.start();
int result = fact.waitFor();
Gives no output
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(executable.getParentFile());
Process fact = builder.start();
try(InputStream inp = fact.getInputStream()){
do{
inp.transferTo(System.out);
}while(factorio.isAlive());
inp.transferTo(System.out);
}
System.out.println();
int result = fact.waitFor();
Prints an empty line.
When I run the same command in the cmd myself, Factorio gives it's console output just fine. It always prints some text with each line prefixed with the number of seconds since the start of the software.
How can I print out the subprocess's output to the console? What did I do wrong in these methods?
This should be relatively easy. Try it with a simple process that you know works first:
Process curl = new ProcessBuilder("curl", "-sD", "-", "https://google.com")
.redirectErrorStream(true)
.start();
// Will block until the end of the input stream.
curl.getInputStream().transferTo(System.out);
I was trying to build up a ProcessBuilder calling the ffmpeg binary.
My problem is that calling it, it returns perfectly under MacOs, Ubuntu and WindowsXp,
but under Windows7 the waitFor() never returns.
Has anyone similar experience under windows 7? Any help would be appreciated!
My command:
ProcessBuilder pb = new ProcessBuilder( );
pb.command( "C:\\Windows\\System32\\cmd.exe", "/c", "c:\\ffmpeg\\bin\\ffmpeg.exe", "-version" );
Tried these ones too:
pb.command( "c:\\ffmpeg\\bin\\ffmpeg.exe", "-version" );
pb.command( "C:\\Windows\\System32\\cmd.exe", "/c", "start c:\\ffmpeg\\bin\\ffmpeg.exe -version" );
Result is the same. :(
Looks like your process writes something in its out and/or err streams. Their buffer overflow and process blocks. You should read out and err streams of your process to avoid this.
See "When Runtime.exec() won't" for more information
If you are using java 7 you could do something like that :
File encodingFile = new File(outfile + ".encoding");
ProcessBuilder pb = new ProcessBuilder(vars.config.ffmpeg, "-i", file, "-y", "-s", width + "x" + height, "-vcodec", "libvpx", outfile); //or other command....
encodingFile.createNewFile();
pb.redirectErrorStream(true);
pb.redirectInput(ProcessBuilder.Redirect.PIPE); //optional, default behavior
pb.redirectOutput(encodingFile);
Process p = pb.start();
// if you want to wait for the process to finish
p.waitFor();
encodingFile.delete();
you should do something like this
ProcessBuilder pb = new ProcessBuilder( );
pb.command( "C:\\Windows\\System32\\cmd.exe", "/c",
"c:\\ffmpeg\\bin\\ffmpeg.exe", "-version" );
Process process = pb.start();
OutputStream stdOutput = process.getOutputStream();
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();
then it will work as your process is giving some output but you are not reading it
I've written an interface to call shell commands from Java for testing purposes. For a few commands, that works quite fine, but for others, the OutputStream of the process never gets ready(). Does anyone have an explanation ? I give the full code:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.err.print("cmd: ");
String line=in.readLine();
The following are all fine for "cat -n", not for "sed s/a/e/"
ProcessBuilder pb = new ProcessBuilder(Arrays.asList(("bash -c \""+line+"\"").split(" ")));
// ProcessBuilder pb = new ProcessBuilder(Arrays.asList(("cmd /C "+line).split(" ")));
// ProcessBuilder pb = new ProcessBuilder("cmd","/C",line);
// ProcessBuilder pb = new ProcessBuilder("bash","-c",line);
// ProcessBuilder pb = new ProcessBuilder(Arrays.asList(line.split(" ")));
Interaction with the process:
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedWriter toP = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader fromP = new BufferedReader(new InputStreamReader(p.getInputStream()));
for(line = in.readLine(); line!=null; line=in.readLine()) {
toP.write(line+"\n");
toP.flush();
System.err.println("stdin: \""+line+"\"");
while(!fromP.ready()); // sed hangs, cat doesn't
System.out.println("result: \""+fromP.readLine()+"\"");
}
One can find plenty of information on ProcessBuilder issues, and for most of them, wrapping stdin and stdout into different Threads seems to be a solution. But if indeed this is the solution, then why ?
An further: Does anyone have an explanation why the straight-forward approach fails and under what circumstances this occurs ? From the example, I can rule out that it is the way the arguments are presented or the specific shell (cmd/bash).
I'm working with Java 1.6 on a Windows7 machine with Cygwin installed, hence both bash and cmd. Could that be a Cygwin issue ?