This question already has answers here:
Java execute command line program 'find' returns error
(2 answers)
Closed 10 years ago.
I am trying to execute a find command using java code. I did the following:
sysCommand = "find . -name '*out*' > file1"
Runtime runtimeObj = Runtime.getRuntime();
try {
Process processObj = runtimeObj.exec(sysCommand);
processObj.waitFor();
...
This Linux command is executed when I use command line but fails in Java, why?
As far as I know, it is not allowable to use any form of piping operator in Runtime.exec. If you want to move the results to a file, you will have to do that part in Java through Process.getInputStream.
If you are interested in doing this in Java then you will want to do something like this:
public void find(File startDirectory, FileFilter filter, List<File> matches) {
File[] files = startDirectory.listFiles(filter);
for (File file:files) {
if(file.isDirectory()) {
find(file, filter, matches);
} else {
matches.add(file);
}
}
}
Then you need but write the FileFilter to accept directories and files that match your pattern.
This question is probably a duplicate or a duplicate.
Anyway, you could use File.list, providing a Filter on the type
of files you want. You could call it recursively to get all sub-directories. I don't love this answer. You would think there is a simpler way.
A friend of mine recommended Commons-Exec from Apache for running a command. It allows you to use a time out on the command. He recommended it because Runtime can have issues with large stdout and stderr.
Related
This question already has answers here:
How to call an external program in python and retrieve the output and return code?
(5 answers)
Closed 2 years ago.
I have a java program that i run with the following command
java -jar <program_name>.jar --<some_parameter> <some_filename>.csv
Within my python script I create the <some_filename>.csv. Then, I would like to execute the java program and use the program's stdout output in my python script.
Is there an easy way to do so?
Try with subprocess:
import subprocess
result = subprocess.run([COMMAND LIST], stdout=subprocess.PIPE)
print(result.stdout)
[COMMAND LIST] is a string list of the words in the command separated by space
Try with this:
import subprocess
p = subprocess.Popen(["java", "-jar <program_name>.jar --<some_parameter> <some_filename>.csv"],shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if not out:
print(err.rstrip().decode())
else:
print(out.rstrip().decode())
I am trying to run a piece of Python code via a Java application. The command when put directly into Command Prompt cd'd to the working directory runs exactly as intended. However, my attempts to use the Runtime and ProcessBuilder classes in conjunction with the Process class has yielded no sign of correct function which would be the creation of a CSV file for every call of the code.
I am running this program using Intellij on Windows 10. I have added each directory I am using to my environmental PATH variable as well as attempting full paths in my commands and just file names. The only source of life I can find is that if I include a .waitFor() method a .isAlive() method will return true before the .waitFor() method is called.
I have searched through various similar questions and concluded that using a ProcessBuilder object is the best way to go and that the biggest issue is probably the structure of my command. However, I have made many iterations and have found nothing that changes the caught error to anything useful.
Here is the privacy augmented code that I have been running, I wrote out the command in full in the process builder as that is the last iteration I have attempted.
for (int y = 1; y < iterator; y++) {
try {
String command =
"C:\\Users\\myName\\AppData\\Local\\Programs\\Python\\Python37\\python C:\\Users\\myName\\IdeaProjects\\projectApplication\\script.py ";
String pythonInputPath = " C:\\Users\\myName\\IdeaProjects\\projectApplication\\bin\\output" + y + ".wav ";
ProcessBuilder pb = new ProcessBuilder(command+Arrays.toString(pythonCommandString).replaceAll("\\s","")+pythonInputPath+Integer.toString(y));
Process p = pb.start();
//Process checks
System.out.println(p.isAlive());
p.waitFor();
System.out.println(p.isAlive());
//Destroying process once complete to ensure smooth iterations
p.destroy();
} catch (Exception ex) {
System.out.println("Problems with python script execution: " + ex);
}
}
They python code takes in a WAV file (pythonInputPath) that is a product of earlier part of the application, an Integer[] that usually includes ~20 values (pythonCommandString), and a single iteration integer (y).
The first call to .isAlive() is true and the second is false as expected however the script normally creates a CSV that should be output to a bin file that exists in the working director and that fails to occur when running from Java. From other examples I expected using the Process builder as opposed to the Runtime stream to work, however, there is no difference in my implementation.
Do not concatenate the program with its arguments. Quoting Oracle ProcessBuilder docs
Each process builder manages these process attributes: a command, a
list of strings which signifies the external program file to be
invoked and its arguments, if any
and
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
Just use the constructor you use, but pass each argument as a separate string, otherwise the OS will try to find an application that is named as a whole command line you gave, and obviously there is no such program
Before you report this as a duplicate, understand that I have now spent a few hours looking over similar questions from a multitude of different websites, many being from here. They do not explain the solution well enough for me to take their answers and apply them to my own problem. If you still feel the itch to report this, go for it. All you'll be doing is preventing me from learning to code better.
I am attempting to call a python script and pass it 5 arguments. I have tried a few different ways to do this and believe the process builder route is my best option. However, I have a few questions as it does not seem to be the right code:
Do I need to be giving process builder a path to an executable, or can I just give it a path to the normal .py file?
Do I need to collect the output from the python file?
If there are any other aspects of the problem I am not seeing, please let me know. My code looks correct compared to others' on the internet doing the same thing. It is listed below:
private void runPython(String pythonPath, HashMap<String, String> map){
pythonPath = "C:/Users/Carlos/PycharmProjects/autoHTML/javaToExcel.py";
try {
ProcessBuilder pb = new ProcessBuilder(pythonPath + "/" + "python", pythonPath, map.get("Driver Advances"), map.get("Driver Loans"),
map.get("Escrow Fund"), map.get("Maintenance Fund"), map.get("Highway Use tax - 2290"));
Process p = pb.start();
catch(Exception e) {
System.out.println("Python error");
}
}
if there is any code you want or any questions you need answered to help me out, please let me know.
To create an operating system processes, you can use ProcessBuilder which takes 2 arguments:
The process to run, here this is the path to your Python executable (a.k.a: "C:/Users/Carlos/PycharmProjects/autoHTML/javaToExcel.py/python.exe" or something similar).
The arguments to pass to your process:
The path to your python script and its own arguments.
You can try with:
ProcessBuilder pb = new ProcessBuilder(
"C:/Users/Carlos/PycharmProjects/autoHTML/javaToExcel.py/python.exe",
pythonPath,
map.get("Driver Advances"),
map.get("Driver Loans"),
map.get("Escrow Fund"),
map.get("Maintenance Fund"),
map.get("Highway Use tax - 2290"));
This question already has answers here:
Run piece of code contained in a String
(9 answers)
Closed 6 years ago.
Lets say i have this String: String run = "System.out.println\(\"Hello\"\)". What i want to do is run what is in the string to output Hello in console.
Maybe there is a method like String.run()?
Try BeanShell , build your app with jar library.
import bsh.Interpreter;
private void runString(String code){
Interpreter interpreter = new Interpreter();
try {
interpreter.set("context", this);//set any variable, you can refer to it directly from string
interpreter.eval(code);//execute code
}
catch (Exception e){//handle exception
e.printStackTrace();
}
}
Maybe in Java 9 you could use the REPL but as it's not there yet You would need to
* create a temporary file with a class with a know to You API
* run javac on it and compile it
* load the compiled class with a class loader
* run the code
If You want to do is running dynamically defined scripts in Your code then You could use Nashorn and JavaScript. It would do what You want. Also You could use Groovy in your project instead of Java - the syntax is similar to Java but Groovy is a dynamic language.
No, you cannot do it and there's no method to run this command in String. Anything withing the double quotes becomes String literals only and compiler doesn't take care of any command written in that.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I run a batch file from my Java Application?
Are there Java classes to run Windows batch files? For example, start the batch files and receive the results of the batch runs?
Apache Commons Exec is a good way to go. Solves several problems you'd encounter if using pure ProcessBuilder or Runtime.exec.
From the project description:
Executing external processes from Java is a well-known problem area. It is inheriently platform dependent and requires the developer to know and test for platform specific behaviors, for example using cmd.exe on Windows or limited buffer sizes causing deadlocks. The JRE support for this is very limited, albeit better with the new Java SE 1.5 ProcessBuilder class.
The usual ProcessBuilder stuff works with batch files, as does Runtime#exec. The command you're executing is cmd.exe, the batch file name is an argument to it. I believe the argument sequence is cmd.exe, /c, batch_file_name. (Edit: Yup, and in fact, I found a question here that this question duplicates on SO where that's in the answer.)
Runtime.getRuntime().exec("cmd /c start batFileName.bat"); should work.
But to read the output from java process, remove start from the above comman.
Yes, according to my knowledge, RunTime classe can. And ofcourse, ProcessBuilder also like that. I have run number of batch files using Java. Following is the google search result. It has links which are equally important
GOOGLE RESULT
If you want to use native Java and no 3rd party packages then try this using Runtime and Process. I'm not the best Java coder in the world but this should get what you want. It might need some modification to add a loop for reading everything from the input stream.
import java.util.*;
import java.lang.*;
import java.io.*;
public class test
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process batch = rt.exec("test.bat");
batch.waitFor();
//exitValue() contains the ERRORLEVEL from batch file
System.out.println(batch.exitValue());
//getInputStream will get all output from stdout
//getErrorStream will get all error output from stderr
InputStream inStream = batch.getInputStream();
byte[] text = new byte[inStream.available()];
inStream.read(text);
System.out.println(new String(text));
}
catch (IOException ex)
{
}
catch (InterruptedException ex)
{
}
}
}