0

I have a requirement to execute a command in terminal using java. I am really stuck up to access terminal window of mac through java code programmatically. It would be really useful if you provide your valuable solutions to perform my task which i have been struggling to do for a past two days. I am also posting the piece of code that I am trying to do for your reference. Any kind of help would be helpful for me

public class TerminalScript
{
 public static void main(String args[]){
 try {
 Process proc = Runtime.getRuntime().exec("/Users/xxxx/Desktop/NewFolder/keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -validity 10000"); 
 BufferedReader read = new BufferedReader(new InputStreamReader(
 proc.getInputStream()));
 try {
 proc.waitFor();
 } catch (InterruptedException e) {
 System.out.println(e.getMessage());
 }
 while (read.ready()) {
 System.out.println(read.readLine());
 }
 } catch (IOException e) {
 System.out.println(e.getMessage());
 }
 }
}

Note: I have to run the command keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -validity 10000 in terminal through java program.

asked Dec 29, 2015 at 19:30
6
  • Can you tell what is your problem? Commented Dec 29, 2015 at 19:46
  • The process is probably waiting for you to read its output, while you are waiting for it to exit. This is a deadlock. Commented Dec 29, 2015 at 19:55
  • keytool is a cli interface to java internal key management APIs I believe. Could you just just use those APIs directly as you are already writing java code? Commented Dec 29, 2015 at 19:58
  • 3
    You missed my point. keytool is a command line tool which just uses java key/keystore/etc. APIs as far as I know. As such you should be able to just use the native APIs directly as you are already writing/running java code. (And that command in your post is just generating a key and not signing anything.) Commented Dec 29, 2015 at 20:28
  • 1
    To expand on Etan's point: Just about everything keytool does can be done with the methods of the java.security.KeyStore class. It's not good practice to use an external process to do something code can do just as well. Also, your use of ready() is incorrect; that method doesn't indicate the end of the data, only whether the next read will block. Commented Dec 29, 2015 at 21:16

1 Answer 1

2

There are a number of problems with your code:

  • keytool sends its prompts to stderr, not stdout, so you need to call proc.getErrorStream()
  • You don't want to buffer the output from keytool as you need to see the prompts
  • You don't want to wait for keytool to terminate
  • As keytool is interactive, you need to read from and write to the process. It might be better to spawn separate threads to handle the input and output separately.

The following code addresses the first three points as a proof of concept and will show the first prompt from keytool, but as @etan-reisner says, you probably want to use the native APIs instead.

 Process proc = Runtime.getRuntime().exec("/usr/bin/keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -validity 10000"); 
 InputStream read = proc.getErrorStream();
 while (true) {
 System.out.print((char)read.read());
 }
answered Dec 29, 2015 at 21:26
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.