Displaying DOS error message using Rhino/JavaScript/Java - java

I am trying to run a DIR command using a program similar to Rhino language (the program is using Java/JavaScript).
If there are any syntax error or any other error, I want to print out the error message using the function below:
function CatchDOSError()
{
var ErrorMSG = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("cmd /c dir \\C:\Test\Data /s /b /a-D > c:\Test\fileRunDIR.txt").getErrorStream()));
while (( ErrorMSG.readLine()) != null)
{
println(ErrorMSG);
}
ErrorMSG.close();
}
If I run this function, all what I get as an output in the console is: "java.io.BufferedReader#71fbs019".
If I run the DOS command from CMD manually, the error message is "The System cannot find the path". This is the error message which I want it to be displayed using the function above. Not sure if there are conversion issues or something wrong with my function.
Any help is appreciated, thank you.

When you do
while (( ErrorMSG.readLine()) != null) {
println(ErrorMSG);
}
You discard the line after checking it wasn't null and then print the Reader itself (which doesn't override toString() and isn't the line). I think you wanted,
var line = "";
while (( line = ErrorMSG.readLine()) != null) {
println(line);
}

Related

Java Runtime.getRuntime() does not print any output or exit code

While running
send = Runtime.getRuntime().exec(myscript)
the script runs as intended but when I try to read any sort of output or exit code, I run into some problems
for example, if my .sh script is just the following two lines
#!/bin/bash
exit 10
printing send.exitValue() returns me exit code 0. Which is not what i am expecting.
This is also in fact after waiting for the program to finish with by using waitFor().
I am also attempting to read the input/output/error streams but they are all null with no values, with the following snippets
val stdInput = BufferedReader(InputStreamReader(send.inputStream))
val stdError = BufferedReader(InputStreamReader(send.errorStream))
send.waitFor()
println("Here is the standard output of the command:\n")
var s: String? = null
while (stdInput.readLine().also { s = it } != null) {
println(s)
}
println("Here is the standard error of the command:\n")
val e: String? = null
while (stdError.readLine().also { s = it } != null) {
println(e)
}
The program I am writing is heavily dependent on the error codes to determine where the program failed if such a case happened. I cannot seem to find out how or why I get 0 as my exit code regardless

Not receiving output from ProcessBuilder in YARN job

I have a Hadoop YARN cluster set up on some machines at my university (all machines running Linux Fedora 25). When running a mapreduce job in YARN, I am unable to receive the output from a call I make to a separate program. Interestingly, if I run my job locally (configured in mapred-site.xml), my method for calling the program and receiving its output works just fine. Below is my executeShellCommand class, which is instantiated and used in my first map task.
public class ExecuteShellCommand {
public String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
String [] args = command.split(" ");
String cmd = args[0];
ProcessBuilder pb = new ProcessBuilder().command(cmd, args[1], args[2], args[3], args[4], args[5], args[6], args[7]).directory(new File("path to executable"));
p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
p.waitFor();
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
return output.toString();
}
}
Things I have made sure to check:
1) Permissions are appropriately set for all files/directories needed
2) Map tasks are run as current user (me), so no issues with illegal access
3) I am not receiving a file not found exception, so the path to the program I'm calling is correct
4) Checked the input/output stream for Process p (input stream set as java.lang.UNIXProcess$ProcessPipeInputStream#1000e80, output stream is null)
5) Instead of calling the program I need to use, I have tried a simple "echo" command, and could not receive that output either.
6) I have also tried using
p = Runtime.getRuntime().exec("myCommand")
but the results are the same (no output received)
As I already mentioned, when I run a job locally, my executeCommand method functions perfectly, and returns the output from the program I call. Only in YARN do the issues occur. I have a feeling that the problem caused by either not reading from the correct buffer, or the command issued to ProcessBuilder is never actually executed. I am quite stumped as to how to debug what is going on here, and any tips would be greatly appreciated!
After hours of trying all sorts of solutions, I figured out how to get the error stream from the process spawned with ProcessBuilder. Turns out when I set the working directory for the process, I forgot to update the path to one of the arguments I was passing it. D'oh!!!

Some Perl lines won't execute from Java Runtime.getRuntime().exec()

I have a strange behavior when calling a perl script from Java.
The perl code is:
#!/usr/bin/env perl
use warnings;
print "dada\n";
$file = "settings.txt";
open $ds, "<", $file;
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
As you can see, in this code I want to read the file "settings.txt" which contents :
1 : a
2 : b
3 : c
4 : d
And this script works when called from cygwin and the output is :
dada
doudou
1 : a
2 : b
3 : c
4 : d
dodo
But when I call it from Java using the following code:
String line;
String cmd = "perl C:\\Data\\Tests\\match_settings.pl";
try {
Process proc = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println("Line :" + line);
}
in.close();
} catch (IOException a) {
// TODO Auto-generated catch block
a.printStackTrace();
}
Then when the Java function is executed, I get the output:
Line :dada
Line :doudou
Line :dodo
Which means that $line = <$ds> is not well executed, but I don't know why.
Any idea ?
Sorry for the long post, wanted to be as precise as possible.
PS : I know some of you are wondering "Why not read the settings.txt file by Java code himself ?" but that's not the question here ;)
It seems that the folder from which your perl code is executed is not the same when executing from Cygwin and Java. So the perl Script can't find your file.
You should add error checking in your perl code, and verify your current working dir directory.
I would write:
#!/usr/bin/env perl
use warnings;
use Cwd;
my $cwd = cwd();
print "dada\n";
print "In folder: $cwd";
$file = "settings.txt";
open ($ds, "<", $file) || die "Can't open settings.txt. Error code: $!";
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
This will help you debug why, when your script is executed from Java, you don't get the expected results.
You should also redirect stderr to stdout in your Java code, so you will get error lines.

Command line argument works in console, fails from within Runtime.getRuntime().exec

Trying to build a basic launcher for a java game. I'm building the proper command to run the application. When the following command executes in the launcher, the launcher closes as expected, but the command doesn't appear to work - either it doesn't work or the game launches and immediately crashes.
When I print this same command to the console and copy/paste it into console and execute manually, it works perfectly.
/**
*
*/
protected void launch(){
currentStatusMsg = "Launching...";
String cmd = "java -jar";
cmd += " -Djava.library.path=\"" +nativesDirectory.getAbsolutePath() + "\"";
cmd += " \""+applicationJar.getAbsolutePath() + "\"";
System.out.println(cmd);
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(cmd);
//closeLauncher();
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Exited with error code "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
I tried adding something to read the output, but nothing is printed.
I was originally using the following format instead, but it has the same effect:
Process pr = Runtime.getRuntime().exec(new String[]{
"java",
"-Djava.library.path=\"" +nativesDirectory.getAbsolutePath() + "\"",
"-jar",
applicationJar.getAbsolutePath()});
Update I realized I was closing the launcher before allowing the debug code to run. The system only prints: "Exited with error code 1"
I finally was able to get the subprocess error to print. It states:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path
However, it should be available because the command I'm executing includes the library path, and when this exact command is run manually, it works fine.
the java command launcher is not a shell. don't use quoting and space separated commands because it won't end well. put each argument into a separate String without any extra quoting, and use the exec(String[]) method.

Running Bash Script in Java

So essentially, I am trying to run the command "/dir/command -arg" to change the LED color on a USB device in Java. I am using Ubuntu 10.04. When I run the command from the terminal, it works just fine.
However, I tried every iteration of Runtime.exec() that I could find and none of them seem to work. I then created a script with the following contents:
#!/bin/bash
echo "hello"
/dir/command -arg
when I run this from a terminal it works just fine. However when I run
#Override
public void run() {
String[] lookupCmd = {"/bin/sh","-c", "sh /dir/script.sh"};
try {
Runtime runtime = Runtime.getRuntime();
Process lookupProc = runtime.exec(lookupCmd);
lookupProc.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(lookupProc.getInputStream()));
String line = reader.readLine();
while (line != null) {
id.add(line);
System.out.println(line);
line = reader.readLine();
}
} catch (Exception e) {
System.err.println(e);
}
}
"hello" print but nothing else. There is no error.
My other command should not yield any output, but simply change the color of an LED. However when I run it with the same command but a different arg which yields an ouput, it still only prints "hello".
I also made sure that my user has permissions to the /dev folder with the usb device.
I wasn't running the error stream, so I've added that.
After that I realized I was missing an environment variable, so added:
String[] envar = {"VAR=path"}
and called:
runtime.exec(lookupCmd, envar);
Works great now.

Categories

Resources