I'm trying to use ProcessBuilder in order to create a tar.zst file that compresses a folder. However, I'm getting the following error after running this code:
try {
ProcessBuilder pb = new ProcessBuilder("tar","--zstd","-cf","info-x.tar.zst","tstpkg");
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
Process process = pb.start();
process.waitFor();
} catch (Exception e){
e.printStackTrace();
}
Error:
tar: Can't launch external program: zstd --no-check -3
And the tar file is created, but is empty.
If I run the same command from the terminal
tar --zstd -cf info-x.tar.zst tstpkg
then it works fine.
When you find a command that works "from the terminal" but not from Java then you should assume that the PATH or other environment required with that command is only set correctly via that terminal, and not when called by JVM.
So, one possible fix is to run your terminal indirectly which may fix the environment needed - depending on your shell and it's setup:
ProcessBuilder pb = new ProcessBuilder("bash", "-c", "tar --zstd -cf info-x.tar.zst tstpkg");
You might also try to fix by setting the correct PATH for running zstd as a sub-process of tar. Check where it is using which zstd and try adding to the PATH before pb.start():
String path = pb.environment().get("PATH"); // use Path on Windows
pb.environment().put("PATH", "/path/to/dir/ofzstd"+File.pathSeparator+path);
Related
I am developing a Java application where one of its task is to execute a system command using Runtime exec. The command requires another JAR file to be able to work but whenever the part where the command will be executed, I am getting an "Error: Unable to access jarfile".
Firstly, my current working directory:
assets/jarFile.jar
myApp.jar
Here's what my code looks like:
try {
// To get the path of the directory where my current running JAR is
String jarPath = myApp.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String path = URLDecoder.decode(jarPath.substring(0, jarPath.lastIndexOf("/")), "UTF-8");
// The system command to execute
String command = "java -Xmx1024m -jar "+path+"/assets/jarFile.jar and-so-on...";
Process p = Runtime.getRuntime().exec(command);
...
}
The jarFile.jar is not an executable JAR by the way.
Any idea?
Seems like your code to find the path of the jar file does not return the correct path.
I'm trying to run this command:
"C:\arduino\arduino --upload --board arduino:avr:nano --port COM3 -v ..\config\config.ino"
It works from my command line. It takes just a few seconds to run & finish.
The problem comes when I try to execute it from Java with:
String cmd = "C:\arduino\arduino --upload --board arduino:avr:nano --port COM3 -v ..\config\config.ino"
Process p = Runtime.getRuntime().exec(cmd);
It takes a minute to execute and ends with:
Launch 4j: an error occurred while starting the application
I've tried with ProcessBuilder too. I've also tried saving the command to a batch file and then running the batch file from Java...but I just got the same result.
EDIT:
If I run the batch file from command line it works too. As I said if I run it from Java, it doesn't.
I've realized that if I run the batch file from another batch file it doesn't work neither.
Maybe there is not a problem at all with Java, but with Arduino IDE.
EDIT 2:
Adding "start" parameter before the command and saving it to a batch file seems to work. Then you just run the batch from java.
Something like this:
arduino.bat
"start C:\arduino\arduino --upload --board arduino:avr:nano --port COM3 -v ..\config\config.ino"
Java code
String s = "PATH TO ARDUINO.BAT"
Process p = null;
ProcessBuilder pb = new ProcessBuilder(s + "arduino.bat");
pb.directory(new File(s));
p = pb.start();
I think the issue is with the relative path at -v argument. Use full path or set
actual working directory with ProcessBuilder.
I am trying to compile a c program from a java program on Linux platform. My snippet is.
ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/gcc",
"-c","/hipad/UserProject/example.c");
Process proc = processBuilder.start();
There is no error during compilation of java program but I am not able to get .o file. I tried to find out solutions but no one is working.
Any suggestion.....
The default working directory of a child process is what ever directory the Java process has as a working directory, which usually is where it was launched from. And by default gcc writes output files to current working directory. That's where you should find example.o.
There are two simple ways to solve this. You can give gcc -o option and full path and name of desired output file, or you can set working directory of child process, like this:
ProcessBuilder processBuilder =
new ProcessBuilder("/usr/bin/gcc", "-c","example.c"); // source in working dir
processBuilder.directory(new File ("/hipad/UserProject")); // or whatever
Process proc = processBuilder.start();
See ProcessBuilder javadoc for more info.
I need to execute linux commands from JSP.
It is working fine.
But i need to start some sh file in a particular directory in linux through JSP. say /home/username/something/start.sh
try{
String command= "cd /home/username/something";
Runtime.getRuntime().exec(command);
Runtime.getRuntime().exec("./start.sh")
out.println("Child");
}
catch(Exception e)
{ out.println("Error");
}
It says FIle or Directory not found.
I tried Runtime.getRuntime().exec("pwd"), It is showing something like "java.lang.UNIXProcess#fc9d2b" !! :O
I need to change the pwd and execute some commands through jsp. How can i do that??
Any help would be appreciated.
You shouldn't (and actually, it seems you can't) set a working directory like that. Each Process object given by Runtime.exec() will have its own working directory.
As answered in How to use “cd” command using java runtime?, you should be using the three argument version of Runtime.exec(), in which you provide a File that will be the working directory. From its javadoc:
Executes the specified command and arguments in a separate process with the specified environment and working directory.
Or even better, use ProcessBuilder along with ProcessBuilder.directory() instead:
ProcessBuilder pb = new ProcessBuilder("start.sh");
pb.directory(new File("/home/username/something"));
Process p = pb.start();
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.