Solved

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

Posted on 2012-03-22
28
1,813 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
  • 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
 
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 500 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
word0 challenge 4 52
wordmultiple challenge 12 89
Python Assistance 7 31
Free Alternative to JIRA 4 55
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

708 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now