I have a program called darknet. It's a C-program made from Darknet.
I want to run the darknet program in a folder Darknet that looks like this:
I'm going to run darknet with Java Process Builder, but I get no responce from it when I run this code:
// Arguments
String darknetNamePath = darknet.getValue().getFilePath().replace("Darknet/", "./");
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/cameraSnap.png";
String thresholdFlag = "-thresh " + thresholds.getValue();
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File("Darknet")); // We need to stand inside the folder "Darknet"
String commandString = "detect " + configurationFlag + " " + weightsFlag + " " + imageFlag + " " + thresholdFlag;
System.out.println("darknetNamePath = " + darknetNamePath);
System.out.println("commandString = " + commandString);
processBuilder.command(darknetNamePath, commandString);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Here is my output. Why doesn't it work for me?
darknetNamePath = ./darknet
commandString = detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.8
Exited with error code : 0
But when I call darknet file via terminal, then it works.
./darknet detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.6
UPDATE 2:
Here is my update.
// Arguments
String darknetNamePath = darknet.getValue().getFile().getAbsolutePath();
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/cameraSnap.png";
String thresholdFlag = "-thresh " + thresholds.getValue();
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(darknetNamePath, "detect", configurationFlag, weightsFlag, imageFlag, thresholdFlag);
Process process = processBuilder.start();
if (process.getInputStream().read() == -1) {
System.out.println(darknetNamePath);
System.out.println("detect");
System.out.println(configurationFlag);
System.out.println(weightsFlag);
System.out.println(imageFlag);
System.out.println(thresholdFlag);
System.out.printf("ERROR!");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Output:
/home/dell/Dokument/GitHub/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Darknet/darknet
detect
cfg/yolov2-tiny.cfg
weights/yolov2-tiny.weights
data/cameraSnap.png
-thresh 0.3
ERROR!
Exited with error code : 0
UPDATE 3:
This works:
// Arguments
String darkPath = darknet.getValue().getFilePath().replace("Darknet/", "./"); // We need to call ./darknet, not absolute path
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/camera.png";
String thresValue = String.valueOf(thresholds.getValue());
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File("Darknet")); // Important
processBuilder.command(darkPath, "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", thresValue);
processBuilder.redirectErrorStream(true); // Important
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Your command must break all arguments into separate pieces - including thresholdFlag. It is a good idea to check if the executable exists. If it does not you should check where it is located or fix your Path variable to ensure that it can be located:
File darkpath = new File(darknetNamePath);
String [] cmd = new String[] { darkpath.getAbsolutePath(), "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", String.valueOf(thresholds.getValue()) };
System.out.println("Path: "+darkpath+ " exists="+darkpath.exists());
System.out.println("exec "+Arrays.toString(cmd));
processBuilder.command(cmd);
It is also worth handling STDERR, the easiest way is to redirect STDERR=>STDOUT before calling processBuilder.start()
processBuilder.redirectErrorStream(true);
If you want Java to launch the executable without prefixing the absolute path it needs to be in one of these directories:
System.out.println("PATH COMPONENTS FOR JAVA LAUNCH:");
Arrays.asList(System.getenv("PATH").split(File.pathSeparator)).forEach(System.out::println);
You are using ProcessBuilder the wrong way. The command method takes a executable and arguments as separate strings, not a path and then another string with the actual command and all its arguments. There is no shell involved to do word splitting on the command, so you pass all your distinct arguments as one argument.
I don't have darknet, so here's a simple command using the Unix echo command:
import java.io.*;
public class ProcessBuilderTest {
public static void main(String[] args) throws Exception {
ProcessBuilder processBuilder = new ProcessBuilder();
String[] command = {"/bin/echo", "hello", "world"};
processBuilder.command(command);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("Exited with error code : " + exitCode);
}
}
When I run this, I get:
robert#saaz:~$ java ProcessBuilderTest.java
hello world
Exited with error code : 0
It's not clear to my why your command doesn't produce an error. If I give a bad command (e.g., a trailing space behind "echo"), I get an exception:
Exception in thread "main" java.io.IOException: Cannot run program "/bin/echo ": error=2, No such file or directory
This may be OS specific. Or maybe you have some other darknet executable that gets picked up.
Related
I would like to execute multiple commands in a cmd shell from java:
sample:
String cmdShell = "cmd /c start cmd.exe /K ";
String endCommand = cmdShell + "\"" + multiplecommands + " && exit" + "\"";
Process proc = Runtime.getRuntime().exec(endCommand);
final BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = input.readLine()) != null) {
LOGGER.debug("" + line);
}
proc.waitFor();
This opens the black window and closes after finished. Is there a way to hide this window. Or any other way to execute multiple commands without showing the cmd window ?
Maybe it useful "start" with "/min":
start /min .....
..........
exit
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/start
you can try this code , in my case this code give all Directory of C:\xampp folder in my console ...without open CMD
public static void main(String[] args)throws Exception {
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd C:\\xampp && C: && dir");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
}
for more study you can read this page
I am writing a java server process that in addition should run vb.exe file with parameters in windows only.
I tried to use ProcessBuilder with start function and Process with exec function but I have no error but nothing happens!
the cmd for example:
"C:\AL500\BIAFLABEL\AddToQueue.exe" "C:\AL500\BiafLabel\Templates\2.xml" -printer \\mickaelbpc\System-N
the command line definitions in the code:
String fullcmd = "\"C:\\AL500\\BIAFLABEL\\AddToQueue.exe\" \"C:\\AL500\\BiafLabel\\Templates\\2.xml\" -printer \\\\mickaelbpc\\System-N";
String fullcmd1 = "C:\\AL500\\BIAFLABEL\\AddToQueue.exe C:\\AL500\\BiafLabel\\Templates\\2.xml -printer \\\\mickaelbpc\\System-N";
String cmd1 = "C:\\AL500\\BIAFLABEL\\AddToQueue.exe";
String cmd2 = "C:\\AL500\\BiafLabel\\Templates\\2.xml";
String cmd3 = "-printer";
String cmd4 = "\\\\mickaelbpc\\System-N";
String[] command = new String[]{cmd1, cmd2, cmd3,cmd4};
Process + array:
File dir = new File("C:/workspace");
Process process = Runtime.getRuntime().exec(command, null, dir);
process.waitFor();
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
String strData;
StringBuffer sb = new StringBuffer("");
BufferedReader brData = new BufferedReader(new
InputStreamReader(stdout));
while ((strData = brData.readLine()) != null)
{
sb = sb.append(strData).append("\r\n");
}
brData.close();
ProcessBuilder + string command with ":
ProcessBuilder pb=new ProcessBuilder(fullcmd);
pb.redirectErrorStream(true);
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
ProcessBuilder + string command with no ":
File log = new File("log");
ProcessBuilder pb=new ProcessBuilder(/*command*/fullcmd1);
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
}
after the changes I am getting this error: "java.io.IOException: Cannot run program "C:\AL500\BIAFLABEL\AddToQueue.exe C:\AL500\BiafLabel\Templates\2.xml -printer \mickaelbpc\System-N": CreateProcess error=2, The system cannot find the file specified" can you please advise?
ProcessBuilder with cmd.exe:
ProcessBuilder pb=new ProcessBuilder("cmd.exe","/c",fullcmd);
pb.redirectErrorStream(true);
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
}
I did all the options and more...if it will be necessary I will add more examples
the vb exe should print a file. any idea how to run it from java process? or what is wrong with my code?
Study the error and output stream of the command. Need to redirect them and stream them in a separate thread. Or try this fronm
File log = new File("log");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Is the full path correct? Can you print the commad line space seperated to a file called run.cmd and run that manually and see what happens from prompt?
which directory are you starting the process from might have to be different than the one that your java program is running at? Process builder has a https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#directory()
To know which directory your java program is using do this:
File f = new File("./");
try{
System.out.println("Start dir is :" + f.getCanonicalFile());
}catch...
https://docs.oracle.com/javase/7/docs/api/java/io/File.html#getCanonicalFile()
i do not think you do not need to add quotes, just set them in the array with actual values. but if running from a .cmd you will need to qualify params with spaces by putting quotes. best to have no spaces in the paths or params when testing.
See github.com/tgkprog/nli/blob/master/RunCmd.java if ur redirecting to log, dont get the stream again in your loop. and dont call via cmd.exe. in my example ignore the actual commmand, put ur exe and params, i just called a sh file as on ubuntu. You call with your 4 params
Im trying to run python script via terminal but it always throws an exception: No such file or directory
StringBuffer output = new StringBuffer();
String command = "python3 Users/lounah/Documents/programming/ApplicationName/scriptName.py " + params.toString();
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
When you pass a string in ProcessBuilder it tries to run a program located in that path.
Instaed you should use a String[] with the path of your executable ( '/python3/python.exe' or 'python' or 'py') followed by the path of your script, followed by the arguments.
String[] command = {
"python3",
"Users/lounah/Documents/programming/ApplicationName/scriptName.py",
params.toString()
};
ProcessBuilder processBuilder = new ProcessBuilder(command);
I am running my Java program from terminal and I am trying to count the number of files in a certain directory using a linux command in my code; I have managed to get output for all other commands but this one.
My command is: ls somePath/*.xml | wc -l
When I run my command in my code, it appears that it has nothing to output, yet when I run the same exact command in terminal it works just fine and actually outputs the number of xml files in that directory.
Here is my code:
private String executeTerminalCommand(String command) {
String s, lastOutput = "";
Process p;
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
System.out.println("Executing command: " + command);
while ((s = br.readLine()) != null){//it appears that it never enters this loop since I never see anything outputted
System.out.println(s);
lastOutput = s;
}
p.waitFor();
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
return lastOutput;//returns empty string ""
}
Updated code w/ output
private String executeTerminalCommand(String command) {
String s, lastOutput = "";
try {
Process p = new ProcessBuilder().command("/bin/bash", "-c", command).inheritIO().start();
//Process p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
System.out.println("Executing command: " + command);
while ((s = br.readLine()) != null){
System.out.println("OUTPUT: " + s);
lastOutput = s;
}
System.out.println("Done with command------------------------");
p.waitFor();
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("LAST OUTPUT IS: " + lastOutput);
return lastOutput;
}
output:
Executing command: find my/path -empty -type f | wc -l
Done with command------------------------
1
LAST OUTPUT IS:
To execute a pipeline, you have to invoke a shell, and then run your commands inside that shell.
Process p = new ProcessBuilder().command("bash", "-c", command).start();
bash invokes a shell to execute your command and -c means commands are read from string. So, you don't have to send the command as an array in ProcessBuilder.
But if you want to use Runtime then
String[] cmd = {"bash" , "-c" , command};
Process p = Runtime.getRuntime().exec(cmd);
Note: You can check advantages of ProcessBuilder here and features here over Runtime
My program requires that I run a .bat file which will compile java source. This is running fine, however I am looking for a solution which will get the output (and possible errors) of compile.bat and add it to a text pane on a GUI. I have the following code, however when executed the process happens without printing anything to the pane and without any errors.
GenerationDebugWindow.main(null);
Process process = rut.exec(new String[] {file.getAbsolutePath() + "\\compile.bat"});
Scanner input = new Scanner(process.getInputStream());
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String line;
int exit = -1;
while ((line = reader.readLine()) != null) {
// Outputs your process execution
try {
exit = process.exitValue();
GenerationDebugWindow.writeToPane(line);
System.out.println(line);
if (exit == 0) {
GenerationDebugWindow.writeToPane("Compilation Finished!");
if(new File(file + "/mod_" + WindowMain.modName.getText()).exists()){
GenerationDebugWindow.writeToPane("Compilation May Have Experienced Errors.");
}
}
} catch (IllegalThreadStateException t) {
}
}
GenerationDebugWindow
private static JTextPane outputPane;
public static void writeToPane(String i){
outputPane.setText(outputPane.getText() + i + "\r\n");
}
Use:
Runtime.getRuntime().exec( "cmd.exe /C " + file.getAbsolutePath() + "\\compile.bat" );
Reference this question: Java Process with Input/Output Stream
It's likely that the output of the process is going to the error stream. However, ProcessBuilder is a more useful class than directly using System.getRuntime().exec()
In the example below, we're telling the ProcessBuilder to redirect the error stream to the same stream as the output goes to, which simplifies the code.
ProcessBuilder builder = new ProcessBuilder("cmd.exe /C " + file.getAbsolutePath() + "\\compile.bat");
builder.redirectErrorStream(true);
builder.directory(executionDirectory); // if you want to run from a specific directory
Process process = builder.start();
Reader reader = ...;
String line = null;
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
int exitValue = process.exitValue();
My program requires that I run a .bat file which will compile java source.
Your users on *nix and OS X require that source be compiled using the JavaCompiler.
The STBC is an example of using the JavaCompiler. It is open source. It uses a JTextArea as opposed to a JTextPane to hold the source and errors, but should be trivial to adapt.