I am trying to run a java class file from another java program.
This is my program:
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
public class RunJava {
public static void main(String[] args) throws IOException {
ProcessBuilder pb = new ProcessBuilder("java","HelloWorld");
pb.directory(new File("/home/local/prasanth-8508"));
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
pb.start();
}
}
After running this program I get the following error:
Exception in thread "main" java.io.IOException: Cannot run program "java"
But when I run any java commands from my terminal, they work absolutely fine.
Another thing I found is, when I run the command: echo $PATH in my terminal and using the ProcessBuilder (ProcessBuilder pb = new ProcessBuilder("bash","-c","echo $PATH");), they are showing different outputs. i.e The path to jdk/bin is not displayed in the ProcessBuilder command.
How can I solve this issue?
Yes, As #MichaelBerry said it is possible that you may not have permission to access it but other then that also I want to include,
Here you have started with very good ProcessBuilder you just need to modify small things like parameter -jar in the constructor of processBuilder.
I've posted below sample code which may help you to understand how it will work.
ProcessBuilder pb = new ProcessBuilder("/path/to/java", "-jar", "your.jar");
pb.directory(new File("preferred/working/directory"));
Process p = pb.start();
Related
In my XPages application I have to call curl commands
The code is simple:
public static InputStream executeCurlCommand(String finalCurlCommand) throws IOException
{
return Runtime.getRuntime().exec(finalCurlCommand).getInputStream();
}
However, it seems that the command isn't executed at all.
When I execute the following (in Linux terminal):
curl -k -i -X GET https://someHost/fws/api/esia/login?redirectUrl=https://redirectHost/sed/gecho/2019/gecho_apps_2019.nsf/Nav2.xsp
I get the output.
But whenever I execute it with Java nothing works. getInputStream() is empty.
At the same time, if I execute this code on my local Windows machine everything is fine. Same goes for the command executed from cmd.
But in XPages there are no exceptions, no errors, just nothing.
Is there a way to debug it?
UPD
If I change the command to something as simple as ls -la everything works fine :x
OK, guys, I figured it out. The thing was that I passed the full command to the shell. It doesn't work in UNUX.
So
You should NEVER use
public static InputStream executeCurlCommand(String finalCurlCommand) throws IOException
{
return Runtime.getRuntime().exec(finalCurlCommand).getInputStream();
}
In UNIX systems. Use ProcessBuilder instead
For example:
ProcessBuilder pb = new ProcessBuilder(
"curl",
"-k",
"-i",
"-X",
"GET",
"http://host.com");
pb.redirectErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
The following method starts the cmd in Windows and it takes a parameter of the command which need to be run.
I have tested this method using the following commands: net users and it worked fine and it printed the users accounts. but if I run the dir command I get the following error:
java.io.IOEXception:
Cannot run program "dir": CreateProcess error=2, The system cannot find the file specified (in java.lang.ProcessBuilder)
Code :
private String commandOutPut;
public void startCommandLine(String s) throws IOException{
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(s); // you might need the full path
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String commandOutPut;
while ((commandOutPut = br.readLine()) != null) {
this.commandOutPut = this.commandOutPut + "\n" + commandOutPut;
}
System.out.println(this.commandOutPut);
}
Well, obviously, your method does not start cmd. How did you get this notion?
The net command is a standalone command so it runs just fine, but the dir command is not standalone, it is an internal command of cmd.exe, so you cannot run it without launching cmd.exe to execute it.
To get it to work you will have to pass not dir but cmd.exe /c dir or something like that.
Don't know if this perception can help you. But, seems that "net users" are recognized as Windows command, since "Execute" dialog can run it.
But, for some reason, the "dir" command aren't. When try to run, Windows responds that command was not found.
Additionaly, I tried run Command with inline arguments too, but the arguments are simply ignored. (sorry for bad english)
My best guess is that this is because "net" is a real executable (there is a file WINDIR\System32\net.exe"), while "dir" is a builtin command of the command interpreter - it has no executable and is directly executed within cmd.exe.
Howevever you may get around this be invoking "dir" command inside the cmd process. The syntax - as per Microsoft docs - is:
cmd /c dir
There are also some related answers on the site:
How to execute cmd commands via Java
Run cmd commands through java
You can use the following code for this
import java.io.*;
public class demo
{
public static void main(String args[])
{
try
{
Process pro=Runtime.getRuntime().exec("cmd /c dir");
pro.waitFor();
BufferedReader redr=new BufferedReader(
new InputStreamReader(pro.getInputStream())
);
String ln;
while((ln = redr.readLine()) != null)
{
System.out.println(ln);
}
}
catch(Exception e) {}
System.out.println("Done");
}
}
I have a command like
cp -R Folder1/* Folder2/
or
rm -r /images/*.gif
It is not working to I try to run a sample program through Java
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
return proc.waitFor();
What am i doing wrong?
When you run a process, Java creates three outputs, the exit code, the STDOUT, and the STDERR. A good program running an external process, will check all three.
You are just waiting for the process to terminate, and return the exit code.
An easy way to see what's happening is to 'inherit' the STDOUT/STDERR streams using a ProcessBuilder:
ProcessBuilder pbuilder = new ProcessBuilder("cp", "-R", "Folder1/*", "Folder2/");
pbuilder.inheritIO();
Process proc = pbuilder.start();
return proc.waitFor();
you will get a better idea of what went wrong.
Note also that I used separate String arguments for the command. This helps with ensuring the arguments are passed right to the underlying process.
Try like this:
List<String> cmd = new ArrayList<String>();
cmd.add("bash");
cmd.add("-c");
cmd.add(" rm -rf *.txt");
add the above list in ProcessBuilder then execute.
Consider a piece of Java code:
import java.io.IOException;
public class Demo{
public static void main(String []args) throws IOException{
...
String abc="i am here";
System.out.println(abc);
}
}
I want to run - echo "THIS IS STUFF FOR THE FILE" >> file1.txt - immediately after the System.out.println() line, assuming file1.txt is in the same directory.
The ProcessBuilder class is the more modern version.
import static java.lang.ProcessBuilder.Redirect.appendTo;
ProcessBuilder pb = new ProcessBuilder("/bin/echo", "THIS IS STUFF FOR THE FILE");
pb.redirectOutput(appendTo(new File("file1.txt")));
Process p = pb.start();
Notice that this calls /bin/echo directly instead of having bash look through the PATH. That's safer, as there is no chance of getting a hacked echo. Also, since this doesn't use bash, Java is used to redirect the output.
Use the Runtime.getRuntime().exec() command like so:
Runtime.getRuntime().exec("echo 'THIS IS STUFF FOR THE FILE!' > file1.txt");
The documentation can be read here.
If it's not working or you find the command handy and want to know more about it, do yourself a favour and read this. It will save you sweat.
I'm trying to run Python, Ruby, C, C++, and Java scripts from a java program, and Processbuilder was suggested to me as a good way to run the scripts. From what I understand, Processbuilder mostly runs native files (.exe on windows, etc.). However, I have heard a few things about running scripts (nonnative) files using Processbuilder. Unfortunately, everything I find on the subject is incredibly vague.
If someone could clarify a way to run nonnative scripts such as Python, Ruby, etc. I would be most grateful!
You can check the ProcessBuilder documentation over at Sunoracle, but basically, you can run the interpreter for the scripting language and pass the script you want to run to it.
For example, let's say you have a script in /home/myuser/py_script.py, and python is in /usr/bin/
class ProcessRunner
{
public static void main(String [] args)
{
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", "/home/myuser/py_script.py");
Process p = pb.start();
}
}
An extremely basic example, you can get fancier with changing the working directory and change the environment.
You can also construct ProcessBuilder with a String array or a subtype of List<String>. The first item in the list should be the program/executable you want to run, and all the following items are arguments to the program.
String pbCommand[] = { "/usr/bin/python", "/home/myuser/py_script.py" };
ProcessBuilder pb = new ProcessBuilder(pbCommand);
Process p = pb.start();
To avoid having to manually enter the entire location of the script, which may also result in portability issues, here's what I did:
String pwd = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", pwd+'/'+scriptName, arg1, arg2);
Process p = pb.start();