?
Solved

Runtime.getRuntime().exec() is not working for "chmod" or even simple "ls" for IBM JRE

Posted on 2012-03-22
28
Medium Priority
?
1,999 Views
Last Modified: 2012-08-13
$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
0
Comment
Question by:MehtaJasmin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 12
  • 3
28 Comments
 
LVL 47

Expert Comment

by:for_yan
ID: 37753106
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
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37753168
Try

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

You need to capture stdout AND stderr
0
 
LVL 47

Expert Comment

by:for_yan
ID: 37753179
For the simplest examnple which must work open notepad.exe in windows
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 86

Expert Comment

by:CEHJ
ID: 37753231
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
0
 

Author Comment

by:MehtaJasmin
ID: 37753296
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
0
 
LVL 47

Expert Comment

by:for_yan
ID: 37753359
well you don't have permission to do chmod  - the permission are of the time when you starteted your java code
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 2000 total points
ID: 37753364
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?
0
 

Author Closing Comment

by:MehtaJasmin
ID: 37753410
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 */
          }
      }
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37753475
Good :) For your 'real' code, look at collectProcessStreams
0
 

Author Comment

by:MehtaJasmin
ID: 37766732
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: :
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37767657
Are you sure that's the exact code you're using?
0
 

Author Comment

by:MehtaJasmin
ID: 37767863
Yes I am. What should I expect as a result from the code that I wrote otherwise?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37768828
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?
0
 

Author Comment

by:MehtaJasmin
ID: 37770827
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.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37771627
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
0
 

Author Comment

by:MehtaJasmin
ID: 37771662
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.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37771776
OK, can you please attach EncryptDecryptUtils.java as a file (you might need to change extension)?
0
 

Author Comment

by:MehtaJasmin
ID: 37771866
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
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37771924
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

0
 

Author Comment

by:MehtaJasmin
ID: 37771977
Here is the calling source file.
EncryptClearTextFilesUsingRSA.java
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37772058
Can you please eliminate whether the catch block was entered by putting in a sysout please?
0
 

Author Comment

by:MehtaJasmin
ID: 37772116
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.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37773907
It might be interesting to revert to the non-collecting method to see if you get the same output or something different
0
 

Author Comment

by:MehtaJasmin
ID: 37776546
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: :
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37776606
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
0
 

Author Comment

by:MehtaJasmin
ID: 37776735
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() + ":");
}
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 37777315
I can't account for this behaviour but i've never worked with AIX
0
 

Author Comment

by:MehtaJasmin
ID: 37777556
Ok, I will try to reproduce this on windows and let you know.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month11 days, 10 hours left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question