how can i execute python script via terminal in Java - java

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);

Related

Java Process Builder - Cannot run a simple program

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.

How to open a program in CMD and interact with it with Java

I am able to open some program, that can get instructions from cmd to do some stuff, like opening file with certain arguments, check if it's ready, etc...
That's how I open file through Java.
final String location = "C:\\Program";
final File dir = new File(location);
String cmd = "cmd.exe /c start my-program.exe";
Process process = Runtime.getRuntime().exec(cmd, null , dir);
How do I interact with it now, send commands like "check_status" or "do_some_stuff" and get it's output to Java.
If I try this:
String [] cmd = {"cmd.exe /c start my-program.exe", "do_stuff"};
Process process = Runtime.getRuntime().exec(cmd, null , dir);
I get error: "Cannot run program "cmd.exe /c start my-program.exe.exe" (in directory "C:\Program"): CreateProcess error=2, The system cannot find the file specified"
But it does finds file when I send single String as an argument.
I understand that I can get it's output to Java this way:
java.io.InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
EDIT: Solved by using getOutputStream.
Writer w = new OutputStreamWriter(process.getOutputStream());
w.write("custom_command");
w.close();
I started Wildfly server with standalone.bat file(similar .exe file)
public static void main(String[] args) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "cd D:\\Users\\turack\\Downloads\\wildfly-16.0.0.Final\\bin\\ && standalone.bat");
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while (true) {
line = bufferedReader.readLine();
if (line == null) { break; }
System.out.println(line);
}
bufferedReader.close();
}
Solved by using getOutputStream.
Writer w = new OutputStreamWriter(process.getOutputStream());
w.write("custom_command");
w.close();

how to run vb exe file from java server side with parameters

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

Not getting input data stream when execute another process from ProcessBuilder

I am new to java and i am calling a Python script from java using processbuilder and trying read python output in java.
ProcessBuilder pb = new ProcessBuilder(Arrays.asList("python","PyScript.py",""+path));
Process p = pb.start();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
{
System.out.println(line);
logger.debug("Value of python output is"+line);
System.out.println("in while loop");
}
readline is getting null. when i run through command prompt its running fine.

Running cmd with spaces from java

I want to run a command through java session. The command contains spaces. as
"C:\With Space\sample.exe" -command_option "C:\Source File\test.c"
This works if
C:\WithoutSpace\sample.exe -command_option "C:\Source File\test.c"
if we keep the quotes in C:\With Space\sample.exe we get error as :'The filename, directory name, or volume label syntax is incorrect.' and if we remove the quotes then the exe do not run...
please guide.
Thanks,
Try this:
String[] arg = {"cmd","/c","C:/Source File/test.c"};
ProcessBuilder pb = new ProcessBuilder(arg);
Process pr = pb.start();
Also, you can use Runtime.exec(String[]) version
Example:
Runtime rt = Runtime.getRuntime();
String[] args = { "cmd", "/c", "C:/Source File/test.c"};
try
{
Process proc = rt.exec(processCommand);
}
You can try this:
Process process = Runtime.getRuntime().exec("'C:\WithoutSpace\sample.exe' -command_option 'C:\Source File\test.c'");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = in.readLine()) != null) {
//line contain command output
}

Categories

Resources