I am trying to invoke a python script from java. The java compiles fine but the python script is not called.
public class javaToPython{
public static void main(String[] args) throws InterruptedException {
try {
Runtime runtime = Runtime.getRuntime();
Process process;
process = runtime.exec("python /home/james/YCSB/bin/pythonycsbcommand.py ");
process.waitFor();
}
catch (IOException ex) {
Logger.getLogger(javaToPython.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
python script:
import os
fo = open("/home/james/YCSB/bin/command.txt", "r+")
str = fo.read()
print "", str
fo.close()
os.system(str)
Edit:
I have tried using the process builder but again with the same results.
ProcessBuilder pb = new ProcessBuilder("python", "/home/james/YCSB/bin/script.py", "-m 2");
Process p = pb.start();
I have tried entering a path that does not exist but the java script still compiles.
Related
I have the following code to run three executions :
public static void main(String[] args) throws InterruptedException, IOException
{
String filepath1 = "cmd /c gradlew jmhJar";
String filepath2 = "cmd /c java -jar path/to/the/file/filename.jar -rf csv -rff path/to/save/file1.csv -wi 3 -i 5 -f 2";
String filepath4 = "cmd /c javac path/to/the/file/ParserHash.java";/*Code to compile is parserHash.java*/
String filepath3 = "cmd /c java path/to/the/compiled/class/ParserHash "C:/Users/msek/Desktop/trial/result/file1.csv C:/Users/msek/Desktop/trial/result/file2.csv C:/Users/msek/Desktop/trial/result/file3.csv";
try
{
runProcess(filepath1);
runProcess(filepath2);
System.out.println("Sucessfully written into file1.csv");
runProcess(filepath4);
System.out.println("Compilation Over");
runProcess(filepath3);
System.out.println("Program Sucessfully Executed");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void runProcess(String processString)
{
try
{
final Process p = Runtime.getRuntime().exec(processString);
new Thread(new Runnable() {
public void run() {
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
try {
while ((line = input.readLine()) != null)
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
p.waitFor();
}
catch (Exception x)
{
x.printStackTrace();
}
}
If I compile the java file going to that particular directory and compile its compiling successfully and on running it, it executes successfully. But if I pass it like "cmd /c path/to/java/file/file.java" its getting compiled but when I execute it, I get an error stating that could not find or load mainclass eventhough class file is present.
I have looked various links on this which suggested buid process, but that didn't work.
I just want to know where I'm going wrong and how to compile, execute a java file by passing multiple arguments using Runtime.exec()..
java path/to/the/compiled/class/ParserHash
If you're having trouble with an exec() you should:
Try the command from a command line yourself. It will fail the same way in this case.
Look up the syntax of the command. In this case you will learn that the argument to the java command is not a path but a class name, fully qualified, i.e. including the package name. With dots.
I want to execute/run this file using Java.
The path is "/usr/local/studio.sh"
I tried:
public class Main {
public static void main(String[] args) {
String[] cmd = {"cd /usr/local","./studio.sh"};
try {
Process p = Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
but it doesn't work. Is there another way?
You can use ProcessBuilder (see https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html) and set the working directory using directory(...) instead of cd command.
In the end something like this:
ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash","/usr/local/studio.sh")
pb.directory(...);
pb.redirectErrorStream(true);
Process p = pb.start();
IOUtils.copy(p.getInputStream(), System.out);
p.waitFor();
This is work fine for me :
public static void main(String[] args) throws InterruptedException, IOException {
String[] cmd = {"/usr/local/android-studio/bin/studio.sh"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
}
Thanks.
The Runtime API has a method to indicate the directory where you want to execute the method:
File folder = new File("/home/user/folder");
Process proc = Runtime.getRuntime().exec(command, null, folder);
The null in this case indicates: "no environment" defined.
Runtime API JavaDoc
I need to execute mysql command by Java and write out the result.
But, only empty file created.
Execution environment is MacOS 10.11.2.
public class Main {
public static void main(String[] args) {
String[] cmd = new String[]{"/bin/sh", "-c", "mysql", "-u", "root", "-ppassword", "databaseName"};
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.redirectInput(ProcessBuilder.Redirect.from(new File("sample.sql")));
builder.redirectOutput(new File("result.tsv"));
try {
Process p = builder.start();
p.waitFor();
System.out.println(builder.redirectInput());
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
sample.sql select * from sample;
when the main method executed, displayed redirect to read from file "sample.sql" on console.
And, result.tsv is still empty.
If I input mysql -u root -ppassword -D sql2xlsx < sample.sql > result.tsv into Terminal.app directly,
result.tsv is not empty, and writed expected results.
I'm trying to run a simple command from console using this
public void execute(File file, String... command){
Process p = null;
ProcessBuilder builder = new ProcessBuilder("ls");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
but it kept saying that I cant run ls, permission denied. Is there any missing step here?
Thanks
You should use pass the commands and the flags to the constructor of the ProcessBuilder separately (as per the docs):
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
It seems you want to execute command, though. To do this, you can pass command to ProcessBuilder's constructor.
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
Here's the ideone to the working code
You'll notice that when I run it with "ls -l", there's a problem executing the command. This is because the first argument is treated as the command to be executed and the remaining arguments are treated as flags.
To change permissions of bash commands in EC2 instances, execute
chmod u+x /home/admin/ec2-api-tools-*/bin/*
This depends on a couple of things:
1) The user that runs java (your process will be ran as that user)
2) The directory where your JAR or class resides.
Also make sure that your account has proper permissions if the java user is not the same as the user you are logged in as.
ProcessBuilder builder = new ProcessBuilder("ls -l");
There is no process named "ls -l". You want to use the process named "ls" with the arguments "-l", for that you need:
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
I am trying to read the output of Psexec into Java using a BufferedReader on a Process InputStream for use on a network however it is only outputting the first line.
Runtime rt = Runtime.getRuntime();
try {
Process p = rt.exec("C:\\Users\\*****\\Desktop\\PS\\Psexec \\\\" + "******" + " -u ****** -p ****** cmd /c dir D:\\");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
log.add("Computer: " + address);
String s = null;
while ((s = stdInput.readLine()) != null) {
log.add(s);
}
} catch (IOException e) {
e.printStackTrace();
}
What would be the reason for this happening and how would this be fixed?
The process is probably producing some of its output on stderr. Either read both the output and the error streams, in separate threads, or use the ProcessBuilder to create the Process, and merge the output streams before you do so, with redirectErrorStream().
So, I spent some time playing around with this, using ProcessBuilder.
I tried redirecting the IO through the INHERITED and PIPE options, but could not get it to display the output of the remote command (the psexec content was fine)
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder(
"C:\\Users\\shane\\Downloads\\PSTools\\PsExec.exe",
"\\\\builder",
"-u",
"xxx",
"-p",
"xxx",
"cmd",
"/c", "dir", "c:\\"
);
try {
Process p = pb.start();
StreamConsumer.consume(p.getErrorStream());
StreamConsumer.consume(p.getInputStream());
System.out.println("Exited with :" + p.waitFor());
} catch (IOException | InterruptedException exp) {
exp.printStackTrace();
}
}
public static class StreamConsumer implements Runnable {
private InputStream is;
public StreamConsumer(InputStream is) {
this.is = is;
}
public static void consume(InputStream is) {
StreamConsumer consumer = new StreamConsumer(is);
new Thread(consumer).start();
}
#Override
public void run() {
try {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
I even tried redirecting the InputStreams to File without any success. It would seem that whatever mechanism psexec is using to stream the results from the remote machine don't seem to be picked up by Java.
You might try PAExec which did work, but didn't seem to wait to exit after the remote command exited...
It could be the case that you started the process and didn't wait for it to finish before checking it's output. If this is the case, your main thread will exit your while loop because it reads null even though the subprocess is still executing. I would suggest using Process.waitFor() so that all of the output ends up in the stream before you begin polling it.