MehtaJasmin
asked on
Runtime.getRuntime().exec() is not working for "chmod" or even simple "ls" for IBM JRE
$java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build pap3260sr10-20111208_01(SR 10))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 AIX ppc-32 jvmap3260sr10-20111207_968 08 (JIT enabled, AOT enabled)
I want to change permission of some files using Java code. If I type in the command, it works fine but when the same command is executed using Runtime.getRuntime().exec( ), its not working. What am I doing wrong?
This is my several trials:
Runtime.getRuntime().exec( "chmod go+rw /sybwork/CURRENT/*.RSA");
Runtime.getRuntime().exec( new String[]{"/bin/ksh","-c"," ls -l *.RSA"});
Even in windows:
Runtime.getRuntime().exec( "cmd.exe /c dir");
does not list directory.
Please help me resolve this.
Thanks
java version "1.6.0"
Java(TM) SE Runtime Environment (build pap3260sr10-20111208_01(SR
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 AIX ppc-32 jvmap3260sr10-20111207_968
I want to change permission of some files using Java code. If I type in the command, it works fine but when the same command is executed using Runtime.getRuntime().exec(
This is my several trials:
Runtime.getRuntime().exec(
Runtime.getRuntime().exec(
Even in windows:
Runtime.getRuntime().exec(
does not list directory.
Please help me resolve this.
Thanks
Try
http://technojeeves.com/joomla/index.php/free/52-runtimeexec
You need to capture stdout AND stderr
http://technojeeves.com/joomla/index.php/free/52-runtimeexec
You need to capture stdout AND stderr
For the simplest examnple which must work open notepad.exe in windows
try {
is the usage for your Unix command
Process p = Runtime.getRuntime()
.exec(new String[] {
"/bin/bash", "-c", "ls -l *.RSA"
});
IOUtils.outputProcessStreams(p);
int exitValue = p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
is the usage for your Unix command
ASKER
My Unix is not bash, its ksh so I changed the command to
Process p = Runtime.getRuntime()
.exec(new String[] {
"/bin/ksh", "-c", "ls -l *.RSA"
});
and it did list the files..
So now I am back to my original problem of changing the permission.
Process p = Runtime.getRuntime().exec( new String[] {"/bin/ksh", "-c", "/sybwork/CURRENT/*.RSA"}) ;
For which the output is now displayed:
/bin/ksh: /sybwork/POLLFILES/L_STS/P ROCESSED/L OSSP/CURRE NT/TLOG_00 28.000000. 011312.ORP OS.001.RSA : 0403-006 Execute permission denied.
126
Process p = Runtime.getRuntime()
.exec(new String[] {
"/bin/ksh", "-c", "ls -l *.RSA"
});
and it did list the files..
So now I am back to my original problem of changing the permission.
Process p = Runtime.getRuntime().exec(
For which the output is now displayed:
/bin/ksh: /sybwork/POLLFILES/L_STS/P
126
well you don't have permission to do chmod - the permission are of the time when you starteted your java code
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you so much CEHJ.
I got all working after setting my code:
{......
String chmodRunCmdStr = "chmod ugo=rwx /sybwork/CURRENT/*.RSA";
Process p = Runtime.getRuntime().exec( new String[] {"/bin/ksh", "-c", chmodRunCmdStr});
outputProcessStreams(p);
int exitValue = p.waitFor();
System.out.println(exitVal ue);
..........}
public static void outputProcessStreams(final Process p) {
Thread runStdout = new Thread() {
public void run() {
copyStream(p.getInputStrea m(), System.out);
}
};
runStdout.start();
Thread runStderr = new Thread() {
public void run() {
copyStream(p.getErrorStrea m(), System.err);
}
};
runStderr.start();
}
/**
* Copy a stream
*
* @param in The source stream
* @param out The target stream
*/
public static void copyStream(InputStream in, OutputStream out) {
try {
byte[] buffer = new byte[DEFAULT_READ_BUFFER_S IZE];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) > -1) {
out.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
/* ignore */
}
try {
out.close();
} catch (IOException e) {
/* ignore */
}
}
I got all working after setting my code:
{......
String chmodRunCmdStr = "chmod ugo=rwx /sybwork/CURRENT/*.RSA";
Process p = Runtime.getRuntime().exec(
outputProcessStreams(p);
int exitValue = p.waitFor();
System.out.println(exitVal
..........}
public static void outputProcessStreams(final
Thread runStdout = new Thread() {
public void run() {
copyStream(p.getInputStrea
}
};
runStdout.start();
Thread runStderr = new Thread() {
public void run() {
copyStream(p.getErrorStrea
}
};
runStderr.start();
}
/**
* Copy a stream
*
* @param in The source stream
* @param out The target stream
*/
public static void copyStream(InputStream in, OutputStream out) {
try {
byte[] buffer = new byte[DEFAULT_READ_BUFFER_S
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) > -1) {
out.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
/* ignore */
}
try {
out.close();
} catch (IOException e) {
/* ignore */
}
}
Good :) For your 'real' code, look at collectProcessStreams
ASKER
CEHJ,
I used collectProcessStreams instead of outputProcessStreams, thinking that I can store the output and display the when I need. I am purposely trying to chmod on file extension that does not exist in the directory:
like:
Here is the code:
But after execution, the screen is as below, I was expecting the message between StrErr or StrOut:
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
1
StrErr: :
StrOut: :
I used collectProcessStreams instead of outputProcessStreams, thinking that I can store the output and display the when I need. I am purposely trying to chmod on file extension that does not exist in the directory:
like:
chmod ugo=rwx /sybwork/CURRENT/*.RSA1
where I don't have any files with 'RSA1' extension.Here is the code:
StringBuilder strErr = new StringBuilder(256);
StringBuilder strOut = new StringBuilder(256);
try
{
Process p = Runtime.getRuntime().exec(new String[] {"/bin/ksh", "-c", chmodRunCmdStr});
//EncryptDecryptUtils.outputProcessStreams(p);
EncryptDecryptUtils.collectProcessStreams(p, strErr, strOut);
int exitValue = p.waitFor();
System.out.println(exitValue);
} catch (Exception e) {
e.printStackTrace();
}
finally
{
System.out.println("StrErr: " + strErr.toString() + ":");
System.out.println("StrOut: " + strOut.toString() + ":");
}
But after execution, the screen is as below, I was expecting the message between StrErr or StrOut:
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
1
StrErr: :
StrOut: :
Are you sure that's the exact code you're using?
ASKER
Yes I am. What should I expect as a result from the code that I wrote otherwise?
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
I'm interested where in the code the above is coming from - do you know?
ASKER
The source line:
Process p = Runtime.getRuntime().exec( new String[] {"/bin/ksh", "-c", chmodRunCmdStr});
where chmodRunCmdStr = "chmod ugo=rwx /sybwork/CURRENT/*.RSA1";
The output is result of execution of this line API. Runtime.getRuntime().exec( )
Because I tried to put debug before and after and this below result line is Unix response for that exec() method execution.
Process p = Runtime.getRuntime().exec(
where chmodRunCmdStr = "chmod ugo=rwx /sybwork/CURRENT/*.RSA1";
The output is result of execution of this line API. Runtime.getRuntime().exec(
Because I tried to put debug before and after and this below result line is Unix response for that exec() method execution.
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
The output is result of execution of this line API. Runtime.getRuntime().exec()
I don't see how it can be - you are meant to have captured stderr and stdout in a StringBuilder. Still - you've altered my code so i can't be sure of much
ASKER
I did not alter your code, I used it:
EncryptDecryptUtils.collec tProcessSt reams(p, strErr, strOut);
because the method takes StringBuilder object, I cretaed before this call and gave it a size of 256 bytes, because default its just 16 bytes for any StringBuilder() constructor. All I am doing is copied your collectProcessStreams() method in my util class.
So yes, I am with you. I should see the error message from stdErr and stdOut object as per my code, but those objects remain empty and the message is displayed outside. Instead of 'finally' block, I tried to strErr.toString() in 'try' block too after exec() call, but did not show any difference.
EncryptDecryptUtils.collec
because the method takes StringBuilder object, I cretaed before this call and gave it a size of 256 bytes, because default its just 16 bytes for any StringBuilder() constructor. All I am doing is copied your collectProcessStreams() method in my util class.
So yes, I am with you. I should see the error message from stdErr and stdOut object as per my code, but those objects remain empty and the message is displayed outside. Instead of 'finally' block, I tried to strErr.toString() in 'try' block too after exec() call, but did not show any difference.
OK, can you please attach EncryptDecryptUtils.java as a file (you might need to change extension)?
ASKER
Ok. Attaching EncryptDecryptUtils.java. One more change that I made in your code is instead of using all copy functions, I used org.apache.commons.io.IOUt ils which has exact same code as yours. I am already using org.apache.commons.io.IOUt ils in several other Java files for this project, so thought of reusing the same instead of adding the same code from your IOUtils class. Attaching org.apache.commons.io.IOUt ils.java as well for your refernce.
EncryptDecryptUtils.java
IOUtils.java
EncryptDecryptUtils.java
IOUtils.java
OK i'll try to have a better look later, for which i'd like your calling source file if possible.
Just as an aside - you don't actually need throwableToString - just
Just as an aside - you don't actually need throwableToString - just
log.error("", e);
ASKER
Here is the calling source file.
EncryptClearTextFilesUsingRSA.java
EncryptClearTextFilesUsingRSA.java
Can you please eliminate whether the catch block was entered by putting in a sysout please?
ASKER
I added this code in catch:
It did not go in catch block, here is the output
chmod version
chmod str: chmod ugo=rwx /sybwork/CURRENT/*.RSA1
1
StrErr: :
StrOut: :
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
catch (Exception e)
{
System.out.println("in catch block : " + e.getMessage());
e.printStackTrace();
}
It did not go in catch block, here is the output
chmod version
chmod str: chmod ugo=rwx /sybwork/CURRENT/*.RSA1
1
StrErr: :
StrOut: :
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
It might be interesting to revert to the non-collecting method to see if you get the same output or something different
ASKER
Not much difference,
here is the code change:
here is the Unix screen text:
hqibm18:/sybwork/POLLFILES /JavaProje ct/Encrypt DecryptFil esUsingRSA $. ./FileEncryptionUsingRSA.k sh
chmod version
chmod str: chmod ugo=rwx /sybwork/CURRENT/*.RSA1
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
exit value : 1
StrErr: :
StrOut: :
here is the code change:
try
{
Process p = Runtime.getRuntime().exec(new String[] {"/bin/ksh", "-c", chmodRunCmdStr});
//Process p = Runtime.getRuntime().exec(new String[] {"/bin/ksh", "-c", "ls -l"});
EncryptDecryptUtils.outputProcessStreams(p);
// EncryptDecryptUtils.collectProcessStreams(p, strErr, strOut);
int exitValue = p.waitFor();
System.out.println("exit value : " + exitValue);
} catch (Exception e) {
System.out.println("in catch block : " + e.getMessage());
e.printStackTrace();
}
finally
{
System.out.println("StrErr: " + strErr.toString() + ":");
System.out.println("StrOut: " + strOut.toString() + ":");
}
here is the Unix screen text:
hqibm18:/sybwork/POLLFILES
chmod version
chmod str: chmod ugo=rwx /sybwork/CURRENT/*.RSA1
chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
exit value : 1
StrErr: :
StrOut: :
That doesn't seem to correspond with your code at all. For instance, where in the above do you request this to be printed?
chmod str: chmod ugo=rwx /sybwork/CURRENT/*.RSA1
ASKER
I did not give you whoe code, please refer the attachment from yesterday. You asked me to provide calling code, and I sent you whole java file EncryptClearTextFilesUsing RSA.java file. I thought you looked at it, so I did not give you whole code again. But here is the source line where that out put is coming from:
String chmodRunCmdStr = chmodRunCmdStrBuff.toStrin g();
System.out.println("chmod str: " + chmodRunCmdStr);StringBuilder strErr = new StringBuilder(256);
StringBuilder strOut = new StringBuilder(256);
try
{
Process p = Runtime.getRuntime().exec( new String[] {"/bin/ksh", "-c", chmodRunCmdStr});
//Process p = Runtime.getRuntime().exec( new String[] {"/bin/ksh", "-c", "ls -l"});
EncryptDecryptUtils.output ProcessStr eams(p);
// EncryptDecryptUtils.collec tProcessSt reams(p, strErr, strOut);
int exitValue = p.waitFor();
System.out.println("exit value : " + exitValue);
} catch (Exception e) {
System.out.println("in catch block : " + e.getMessage());
e.printStackTrace();
}
finally
{
System.out.println("StrErr : " + strErr.toString() + ":");
System.out.println("StrOut : " + strOut.toString() + ":");
}
String chmodRunCmdStr = chmodRunCmdStrBuff.toStrin
System.out.println("chmod str: " + chmodRunCmdStr);StringBuilder strErr = new StringBuilder(256);
StringBuilder strOut = new StringBuilder(256);
try
{
Process p = Runtime.getRuntime().exec(
//Process p = Runtime.getRuntime().exec(
EncryptDecryptUtils.output
// EncryptDecryptUtils.collec
int exitValue = p.waitFor();
System.out.println("exit value : " + exitValue);
} catch (Exception e) {
System.out.println("in catch block : " + e.getMessage());
e.printStackTrace();
}
finally
{
System.out.println("StrErr
System.out.println("StrOut
}
I can't account for this behaviour but i've never worked with AIX
ASKER
Ok, I will try to reproduce this on windows and let you know.
First try direct commads - there amy be some issues when you first start additional she'll like with "cmd..exe /c dir"
First try just "dir"
and also make sure you capture the output stream from java- how would you know that it works?
The same from Unix - try direct command -
why this does not work is strange:
Runtime.getRuntime().exec(
maybe the privileeges issue
when you start another shell within - it may be more tricky