Java Runtime.getRuntime().exec() appears to be overwriting $PATH - java

For a project to automate some mutation adequacy testing, I'm trying to make GoLang from source from inside a Java program. I have been able to make it from source in the Terminal, and have tried using that command in Java's Runtime.getRuntime().exec() command:
String[] envp = new String[3];
envp[0] = "CC=/usr/bin/clang";
envp[1] = "GOROOT_BOOTSTRAP=/usr/local/go";
envp[2] = "CGO_ENABLED=0";
Runtime.getRuntime().exec("./all.bash", envp, "$HOME/Desktop/go/src");
The equivalent command to this works fine in the Terminal. Running this code in java (And printing the output) gets the following:
./all.bash
##### Building Go bootstrap tool.
cmd/dist
go tool dist: FAILED: uname -r: exec: "uname": executable file not found in $PATH
So that's weird that it can't find uname. Again, if I enter 'uname' on the Terminal, it works fine. So I found the directory of uname ('which uname' gives '/usr/bin/uname') and set $PATH to that for this command:
String[] envp = new String[4];
envp[0] = "CC=/usr/bin/clang";
envp[1] = "GOROOT_BOOTSTRAP=/usr/local/go";
envp[2] = "CGO_ENABLED=0";
envp[3] = "PATH=/usr/bin";
Runtime.getRuntime().exec("./all.bash", envp, "$HOME/Desktop/go/src");
And that instead gets the output:
./all.bash
env: bash: No such file or directory
So when I set the path, it can't find the program in the directory. This suggests to me that when Runtime.getRuntime().exec() is called, it overwrites $PATH to be the directory I passed it, then overwrites the environment variables I gave it. But in order for ./all.bash to work, I need both paths to be in the $PATH variable. How can I do this?
On Mac OS X 10.11.6.

Runtime.exec was replaced by ProcessBuilder twelve years ago, as part of Java 1.5.
Among its many superior features is the ability to add to the existing environment:
ProcessBuilder builder = new ProcessBuilder("./all.bash");
builder.inheritIO();
builder.directory(
new File(System.getProperty("user.home") + "/Desktop/go/src"));
builder.environment().put("CC", "/usr/bin/clang");
builder.environment().put("GOROOT_BOOTSTRAP", "/usr/local/go");
builder.environment().put("CGO_ENABLED", "0");
builder.start();

Related

Why the commands written in a .bat running infinitely in java?

I have a .bat file whose job to find the version of the java. The command written inside the bat file is java -version (This is just an example, don't suggest alternative ways to get java version)
Code to run the .bat file:
String path = "cmd /c start d:\\java.bat";
Runtime rn = Runtime.getRuntime();
Process pr = rn.exec(path);
The bat file is running but running in a loop. But the expected behavior is it should open the command prompt and run the command only once
Because the name of the file is same as the command within it, the java.bat file is itself called from the java -version command. Just renaming the .bat file, or using java.exe -version would stop the issue.
Since extension for such executables and batch files is optional (*), the filename itself can be used alone as a command, read more about it here
(*) check great in-depth comment by #Compo
Also here is an example Java Bat =)
check java library instead of using a .bat file
Version version = java.lang.Runtime.version();
System.out.println("Java Version = "+version);
System.out.println("Java Version Feature Element = "+version.feature());
System.out.println("Java Version Interim Element = "+version.interim());
System.out.println("Java Patch Element Version = "+version.patch());
System.out.println("Java Update Element Version = "+version.update());
System.out.println("Java Version Build = "+version.build().get());
System.out.println("Java Pre-Release Info = "+version.pre().orElse("NA"));
here is source
I got the answer myself..
in stead of writing the commands simply in the bat file we can write in the below way and it worked for me
call java -version
Thanks,
Sudhansu

Opening a PDF in java using Linux Terminal

I'm trying to open a PDF file in Linux with the xdg-open command in java.
String[] command = {"xdg-open","\""+path+"\""}
Process p = Runtime.getRuntime().exec(command,null);
p.waitFor();
When I run the code in terminal nothing happens even tho if I type it in terminal:
xdg-open path
it opens the PDF.
Any ideas whats wrong?
You should not escape the path: if the program was called, it was with an invalid path ("path" and not path).
String[] command = {"xdg-open", path}
The Runtime.getRuntime().exec(command,null); will use ProcessBuilder internally which, in the case of Linux, should invoke the system command execve.

Command is executable in terminal that I opened, but cannot execute when I use java function to open terminal and execute it

I am trying to write a java program that can open terminal and input a command to it. The command is "wrspice" which can start an application. I have added "wrspice" PATH in .bashrc and it works fine. But when I write a java code using ProcessBuilder to execute, it pop up "bash: wrspice: command not found" error. Here is my java code:
final String[] wrappedCommand;
wrappedCommand = new String[]{ "xterm", "-hold", "-e", "wrspice"};
Process process = new
ProcessBuilder(wrappedCommand).redirectErrorStream(true).start();
This code works fine when I replace "wrspice" with "ls" to print the file list. But when I try "wrspice" it gives me error for "command not found".
Here is how I add "wrspice" in .bashrc:
export PATH=/usr/local/xictools/bin:$PATH
Anyone have any ideas? Thanks in advance.
Java isn't an interactive shell. Specify the full-path to your command instead. And you don't need new String[]. Like,
wrappedCommand = { "xterm", "-hold", "-e", "/usr/local/xictools/bin/wrspice"};
You should probably specify the path to xterm as well. Double check on your system.
wrappedCommand = { "/usr/bin/xterm", "-hold", "-e", "/usr/local/xictools/bin/wrspice"};

Using Runtime.getRuntime().exec() in Mac OS causes error

I am trying to use this code in my Java application to run another Jar in Mac OS X :
Runtime runtime = Runtime.getRuntime();
String cmd = "java -Xmx1024m -jar \"/Volumes/NANO PRO/My Program/Main.jar\"";
Process process = runtime.exec( cmd );
If Main.jar exists in a path with no spaces it will work fine, but since it exists in a path with spaces, it causes the error :
Is there a way to make this run in a path that has spaces ?
Use an array to build different parts of your command and leave it to Java runtime to convert them appropriately based on the underlying environment.
String [] cmd = {"java",
"-Xmx1024m",
"-jar",
"/Volumes/NANO PRO/My Program/Main.jar"};
Also you can take a look at ProcessBuilder:

Problem executing a batch file in a Java application

I have batch file, named run.bat which inlcudes the following code:
#echo off
REM bat windows script
set CXF_HOME=.\lib\apache-cxf-2.2.7
java -Djava.util.logging.config.file=%CXF_HOME%\logging.properties -jar archiveServer-0.1.jar
When I execute this file on a command line it works perfectly. However when I try to execute within a java file with the following statement:
File path = new File("C:/Documents and Settings/Zatko/My Documents/Project-workspace/IUG/external/application/archive");
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", "start", "run.bat"}, new String[]{}, path);
I get the following error in the terminal window:
'java' is not recognized as internal or external command, operable program or batch file.
Where the error may be?
Java.exe is not found in your PATH.
If you can assume that the JAVA_HOME variable is defined, you can modify your batch file:
%JAVA_HOME%\bin\java -Djava.util.logging.config.file=%CXF_HOME%\logging.properties -jar archiveServer-0.1.jar
A better way to do it would be, as staker suggested, to set the PATH environment variable to contain %JDK_HOME%\bin
File workingDirectory = new File("C:/Documents and Settings/Zatko/My Documents/Project-workspace/IUG/external/application/archive");
String javaProgram = System.getProperty("java.home") + "\bin";
String[] command = {"cmd.exe", "/C", "start", "run.bat"};
String[] environment = {"PATH=" + javaProgram};
Process process = Runtime.getRuntime().exec(command, environment, workingDirectory);
As a third option, you can also avoid to have the batch file by invoking the main-class of the jar directly. You archiveServer would run in the same process, however. Maybe that's not want you want.
I suppose you didn't add JAVA_HOME/bin to your PATH environment variable.

Categories