Unable to run linux commands using Java - java

I am using ProcessBuilder to run a Linux command on a server:
ProcessBuilder pb = new ProcessBuilder("/usr/bin/printf %b", sendMessage,
URL, " #serendipity | /usr/bin/perl /usr/local/bin/foo/bar -u nagios -s");
I am trying to broadcast a message that will be piped to a paging system called bar. But when executing the jar file on the server, I constantly get this:
java.io.IOException: Cannot run program "/usr/bin/printf %b": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at sms_serendipity.sms_serendipity.SmsSendMessage.sendMessage(SmsSendMessage.java:59)
at sms_serendipity.sms_serendipity.SmsSendMessage.randomizeLinks(SmsSendMessage.java:48)
at sms_serendipity.sms_serendipity.SmsParseWeb.regexHttp(SmsParseWeb.java:103)
at sms_serendipity.sms_serendipity.SmsParseWeb.parseXML(SmsParseWeb.java:77)
at sms_serendipity.sms_serendipity.SmsParseWeb.locateWebAudio(SmsParseWeb.java:44)
at sms_serendipity.sms_serendipity.mainClass.main(mainClass.java:11)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 6 more
It's my first time using ProcessBuilder (I have also tried with Runtime.exec() as well). Can someone tell me what I may do to correct the command I am trying to run?

Read the error message carefully: you try to execute the program /usr/bin/printf %b which of course does not exist.
The program is called /usr/bin/printf.

I have figured out a way of getting this working. It took a bit of experimenting but here is what I did.
ProcessBuilder pb = new ProcessBuilder(
"/bin/dash",
"-c",
"/usr/bin/perl /usr/local/bin/foo/bar -u nagios -s " + sendMessage + URL + fooUser,
"/bin/echo");
I had it log the stdout to a text file and confirmed that the broadcast works.

Related

Getting No such File or Directory Exception on Ubuntu when trying compile a java project from java.lang.Process

Recently, I have switched to Ubuntu v20.04 from Windows 10 Pro v2004 because of performance purposes. When, I was on Windows I can freely compile a java project from another java program by writing:
String pathToCompiler = "\"C:/Program Files/Java/jdk-14/bin/javac\"";
Process compileProcess = Runtime.getRuntime().exec(pathToCompiler+" -d bin #.sources", null, new File("ProjectPath"))
Where the sources file is a file containing the list of classes of the project
The code above works successfully on Windows 10.
But On Linux(Ubuntu):
if I substitute the value of variable pathToCompiler as
pathToCompiler = "\"/usr/lib/jvm/java-11-openjdk-amd64/bin/javac\""
the below exception is raised up and the program executing the command exits:
"/usr/lib/jvm/java-11-openjdk-amd64/bin/javac" -d bin #.sources
java.io.IOException: Cannot run program ""/usr/lib/jvm/java-11-openjdk-amd64/bin/javac"" (in directory "/home/arham/Documents/Omega Projects/Project0"): error=2, No such file or directory
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at java.base/java.lang.Runtime.exec(Runtime.java:592)
at java.base/java.lang.Runtime.exec(Runtime.java:416)
at ide.utils.systems.BuildView.lambda$3(BuildView.java:267)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.io.IOException: error=2, No such file or directory
at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:340)
at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:271)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
The problem is that the file actually exists but it says No Such File or Directory
Actually, The program which is compiling the project is a Java IDE that I am creatiing.
Someone please tell if he/she knows how to fix this bug
The Runtime.exec method has several problems that make it difficult to use, and this is one of them. Use the newer ProcessBuilder class instead.
String pathToCompiler = "C:/Program Files/Java/jdk-14/bin/javac";
Process compileProcess = new ProcessBuilder(pathToCompiler, "-d", "bin", "#.sources")
.directory(new File("ProjectPath"))
.start();
The differences are:
Remove the extra quotes from around the path to the executable. If quoting is needed, the system takes care of it.
Pass the each command line arguments as a separate string. This way you don't have to worry about quoting.
Update the path to the following:
String pathToCompiler = "/usr/lib/jvm/java-11-openjdk-amd64/bin/javac/";

Java: No such file or directory when redirecting command line program output to /dev/null

I'm currently working on invoking bash program using java. The bash program output too much message and I want to redirect them to /dev/null. But I encountered a weird error No such file or directory.
Here is my demo.
public static void main(String[] args) {
try {
// Another version I've tried:
// Process p = Runtime.getRuntime().exec("echo a > /dev/null");
ProcessBuilder b = new ProcessBuilder("echo a");
// b.redirectOutput(new File("/dev/null")).redirectErrorStream(true);
b.redirectOutput(ProcessBuilder.Redirect.to(new File("/dev/null")))
.redirectErrorStream(true);
Process p = b.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
And the error message as follows:
java.io.IOException: Cannot run program "echo a": error=2, No such file or directory
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at test.main(test.java:12)
Caused by: java.io.IOException: error=2, No such file or directory
at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:340)
at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:271)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
... 2 more
I'm using a MacBook with Catalina, and I tried java 1.8.0_231 and 1.8.0_241 from oracle. (I couldn't use higher java version because one of the dependency of my project requires java 8).
To ignore the output from the process, it's easier and more portable to use ProcessBuilder.Redirect.DISCARD than explicitly redirecting to a special file/device such as /dev/null.
b.redirectOutput(ProcessBuilder.Redirect.DISCARD)
.redirectErrorStream(true);
Forget about using Runtime.exec - that method is badly designed and hard to use safely. If you want to do input redirection with the "> /dev/null" style, you need to remember that > is a construct created by the command interpreter shell, not the operating system, and if you want to use it you must run a shell.
Runtime.getRuntime().exec(new String[] {"sh", "-c", "echo a > /dev/null"});

ProcessBuilder fails on command that includes local environment variable

I can execute usual commands on Linux, wrapped by the processBuilder. But I'm currently trying to run the minecraft server like in the following example, with some variable set before the command, and it fails with an exception.
final ProcessBuilder processBuilder = new ProcessBuilder("LD_LIBRARY_PATH=. ./bedrock_server");
processBuilder.directory(MC_PAL_LOCATION_DIR.toFile());
process = processBuilder.start();
Exception:
java.io.IOException: Cannot run program "LD_LIBRARY_PATH=. ./bedrock_server" (in directory "/home/user/Desktop/minecraft_bedrock_server_t"): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at controller.Server.startMinecraftServer(Server.java:91)
at controller.Server.start(Server.java:58)
at Bootstrapper.bootServer(Bootstrapper.java:67)
at Bootstrapper.main(Bootstrapper.java:30)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 4 more
Exception in thread "Thread-0" java.lang.NullPointerException
at controller.ConsoleInput.run(ConsoleInput.java:16)
at java.lang.Thread.run(Thread.java:748)
Is there any possibility to use the processBuilder for such commands? The command works if I paste it directly to the terminal.
Link to server: https://minecraft.net/en-us/download/server/bedrock/
Command: LD_LIBRARY_PATH=. ./bedrock_server
You can't use bash shell commands like that without bash. But you can manipulate the environment yourself programmatically. Like,
final ProcessBuilder processBuilder = new ProcessBuilder("./bedrock_server");
processBuilder.environment().put("LD_LIBRARY_PATH", ".");
processBuilder.directory(MC_PAL_LOCATION_DIR.toFile());
process = processBuilder.start();
As #ElliottFrisch pointed out, you cannot use shell command without bash, therefore you either add LD_LIBRARY_PATH to environment map or execute bash:
final ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", "LD_LIBRARY_PATH=. ./bedrock_server");
processBuilder.directory(MC_PAL_LOCATION_DIR.toFile());
process = processBuilder.start();

The system cannot find the file specified at java.lang.ProcessBuilder.start

I am a novice at programming. I have recently tried to download the source code of an open source software and setup the environment. However, I am seeing the following issue when I tried to run the build for the first time:
Execute failed: java.io.IOException: Cannot run program "unzip" (in directory "....\"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start
Any tips on how to resolve this issue?
From what I understand, it is unable to a file:
where exactly to look for ProcessBuilder.start
How do I modify it?
Try this:
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("Write command here").start();
Edit: Command - string array which begin with fullpath to your programm. For example:
processBuilder.command("C:\\Program Files (x86)\\Microsoft Office\\Office15\\OUTLOOK.exe").start();

ProcessBuilder can't find perl

I'm trying to execute a perl script from java with the following code:
ProcessBuilder script =
new ProcessBuilder("/opt/alert-ssdb.pl");
Process tmp = script.start();
But when I execute it it returns
java.io.IOException: Cannot run program "/opt/alert-ssdb.pl": java.io.IOException: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:488)
at scripttest.main(scripttest.java:11)
Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.<init>(UNIXProcess.java:164)
at java.lang.ProcessImpl.start(ProcessImpl.java:81)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
... 1 more
about the file
ls -l alert-ssdb.pl
-rwxr-xr-x. 1 root root alert-ssdb.pl
I tried running /usr/bin/perl/ with the script as an argument and it also failed with the same exception.
/bin/ls and other simple commands run without a problem though.
Also the first line of the script is #!/usr/bin/perl
and when run on command line it works
what am I missing?
//Update:
The big picture is that I'm trying to call the script via a storm bolt and it fails at that point.
I managed to make it work by defining a python script as a bolt
using
super(python,myscript.py)
(myscript imports the storm library) and from myscript I call the perl script.
I haven't tried yet but I suppose that If I modify the perl script to be a storm bolt it will run nicely.
Try changing
new ProcessBuilder("/opt/alert-ssdb.pl");
to:
new ProcessBuilder("/usr/bin/perl", "/opt/alert-ssdb.pl");
I've had past experiences where not all my environment variables from the shell exist when using ProcessBuilder.
Edited to reflect #dcsohl's comment.

Categories

Resources