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(SR10))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 AIX ppc-32 jvmap3260sr10-20111207_96808 (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
MehtaJasminAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

for_yanCommented:
One thing - make sure that you are running java under the same privileges as you run command line direcly (uaully from the same prompt should be OK)

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("chmod go+rw /sybwork/CURRENT/*.RSA");
maybe the privileeges issue

when you start another shell  within - it may be more tricky
CEHJCommented:
Try

http://technojeeves.com/joomla/index.php/free/52-runtimeexec

You need to capture stdout AND stderr
for_yanCommented:
For the simplest examnple which must work open notepad.exe in windows
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

CEHJCommented:
try {
            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();
        }

Open in new window


is the usage for your Unix command
MehtaJasminAuthor Commented:
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/PROCESSED/LOSSP/CURRENT/TLOG_0028.000000.011312.ORPOS.001.RSA: 0403-006 Execute permission denied.
126
for_yanCommented:
well you don't have permission to do chmod  - the permission are of the time when you starteted your java code
CEHJCommented:
My Unix is not bash, its ksh so I changed the command to

Sorry - left in bash after testing

Process p = Runtime.getRuntime().exec(new String[] {"/bin/ksh", "-c", "/sybwork/CURRENT/*.RSA"});

Open in new window


That will try to execute all .RSA files as scripts - is that your intention?

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MehtaJasminAuthor Commented:
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(exitValue);
..........}

public static void outputProcessStreams(final Process p) {
        Thread runStdout = new Thread() {
            public void run() {
                copyStream(p.getInputStream(), System.out);
            }
        };

        runStdout.start();

        Thread runStderr = new Thread() {
            public void run() {
                copyStream(p.getErrorStream(), 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_SIZE];
          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 */
          }
      }
CEHJCommented:
Good :) For your 'real' code, look at collectProcessStreams
MehtaJasminAuthor Commented:
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:
chmod ugo=rwx /sybwork/CURRENT/*.RSA1

Open in new window

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() + ":");
}

Open in new window


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: :
CEHJCommented:
Are you sure that's the exact code you're using?
MehtaJasminAuthor Commented:
Yes I am. What should I expect as a result from the code that I wrote otherwise?
CEHJCommented:
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?
MehtaJasminAuthor Commented:
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.

chmod: /sybwork/CURRENT/*.RSA1: A file or directory in the path name does not exist.
CEHJCommented:
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
MehtaJasminAuthor Commented:
I did not alter your code, I used it:

EncryptDecryptUtils.collectProcessStreams(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.
CEHJCommented:
OK, can you please attach EncryptDecryptUtils.java as a file (you might need to change extension)?
MehtaJasminAuthor Commented:
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.IOUtils which has exact same code as yours. I am already using org.apache.commons.io.IOUtils 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.IOUtils.java as well for your refernce.
EncryptDecryptUtils.java
IOUtils.java
CEHJCommented:
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


log.error("", e);

Open in new window

MehtaJasminAuthor Commented:
Here is the calling source file.
EncryptClearTextFilesUsingRSA.java
CEHJCommented:
Can you please eliminate whether the catch block was entered by putting in a sysout please?
MehtaJasminAuthor Commented:
I added this code in catch:

 
catch (Exception e) 
{
  System.out.println("in catch block : " + e.getMessage());
 e.printStackTrace();
}

Open in new window


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.
CEHJCommented:
It might be interesting to revert to the non-collecting method to see if you get the same output or something different
MehtaJasminAuthor Commented:
Not much difference,

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() + ":");
}

Open in new window


here is the Unix screen text:

hqibm18:/sybwork/POLLFILES/JavaProject/EncryptDecryptFilesUsingRSA $. ./FileEncryptionUsingRSA.ksh
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: :
CEHJCommented:
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
MehtaJasminAuthor Commented:
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 EncryptClearTextFilesUsingRSA.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.toString();
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.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() + ":");
}
CEHJCommented:
I can't account for this behaviour but i've never worked with AIX
MehtaJasminAuthor Commented:
Ok, I will try to reproduce this on windows and let you know.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.