0

I have tried to use ProcessBuilder to execute commandline process from java class.
A successful execution actually opens up another terminal within my eclipse.
*which is like: *
Process ----> opens up ----> subprocess
rest of all the commands has to be executed in the subprocess

Someone help me out to understand how to trigger a subprocess and once finished exit from the same.

List commands = new ArrayList<String>();
 commands.add("mysql -u root -p ********");
 commands.add("select * from employee;");
 System.out.println(commands);
ProcessBuilder pb = new ProcessBuilder(commands);
Process process = pb.start();


NB:

Given command is just as an example, question is not related to 'jdbc', its all about the process & subprocess.

asked May 26, 2017 at 12:04
2
  • It should exit from the main process, show us the code. Commented May 26, 2017 at 12:06
  • Edited with the code which I am trying to execute, which will start the main process only, how to start the subprocess on top of this process. Commented May 26, 2017 at 12:09

3 Answers 3

1

You have misunderstood how operating system processes are invoked.

Each process consists of the program name (like notepad.exe or java.exe), and zero or more command line arguments.

A ProcessBuilder is capable of running one command at a time. The List of Strings that form its command are not separate commands; they represent the program name and its individual command line arguments.

Therefore, to run mysql, you would need to separate the command line arguments:

ProcessBuilder pb = new ProcessBuilder("mysql", "-u", "root", "-p", password);

Your next line, select * from employee;, is not a system command and is not a subprocess. It’s a mysql command—a directive understood by mysql only. You can probably write it to the standard input of the mysql process, because mysql happens to accept commands via standard input:

try (Writer writer = new OutputStreamWriter(process.getOutputStream())) {
 write.write("select * from employee;");
}

Not all programs accept commands via their standard input, however.

As you seem to be aware, mysql would not be a good candidate for an external process. Reading and parsing the output would be more difficult than it may look at first glance. JDBC would be the better choice. (You seem to know this, but I mention it for the benefit of other readers.)

answered May 26, 2017 at 14:56
Sign up to request clarification or add additional context in comments.

2 Comments

well explained in laymans terms, great.. However it looks like similar answer. The need is not at all about myslq/jdbc. And there is a subprocess involved in the next step, I couldn't explain it better than this one. So its all about assuming that the query is another subprocess. The challenging task would be parse the output and point out the result values only.
How to make an external process spawn a subprocess of its own depends entirely on what the external process is. There is no universal way to make one process start another process.
0

Looking at your example it looks like you're trying to run sql commands on mysql.

First if you really want to do this with the msqyl command line command, you want to redirect it's input/outputs to java InputStream/OutputStream and then send your SQL request to mysql process input. You may probably follow this sample:

 List<String> command = new ArrayList<>();
 command.add("mysql -u root -p ********");
 ProcessBuilder pb = new ProcessBuilder(command);
 Process process = pb.start();
 PrintStream commandIn = new PrintStream(process.getOutputStream());
 commandIn.println("select * from employee;");

Second the best way of running SQL commands on your mysql instance is to use JDBC and not the mysql command line tool. Look for the numerous JDBC tutorials out there.

Here is a more complete (and working) example. Look at this "command line tool":

public class TestCmd {
 public static void main(String[] args) throws IOException
 {
 System.out.println("Started. args[0]=" + args[0]);
 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 for(;;)
 {
 String line = in.readLine();
 if (line == null) break;
 System.out.println("echo:" + line);
 }
 }
}

And then the "driver" program witch demonstrate how to send commands to this command line tool:

public class TestDriver {
 final static String JAVA_EXE = "C:\\...\\java.exe";
 final static String CLASS_BASEPATH = "C:\\...\\java\\bin";
 public static void main(String[] args) throws Exception
 {
 List<String> command = new ArrayList<>();
 command.add(JAVA_EXE.toString());
 command.add("-classpath");
 command.add(CLASS_BASEPATH);
 command.add("TestCmd");
 command.add("Parameter");
 ProcessBuilder pb = new ProcessBuilder(command);
 pb.redirectOutput(new File("c:\\temp\\out.txt"));
 Process process = pb.start();
 PrintStream commandIn = new PrintStream(process.getOutputStream());
 commandIn.println("first input line");
 commandIn.flush();
 commandIn.println("second input line");
 commandIn.flush();
 // give some time to the sub process to finish writing its output
 Thread.sleep(100);
 process.destroy();
 }
}

In the output "out.txt" you will get, as expected:

Started. args[0]=Parameter
echo:first input line
echo:second input line
answered May 26, 2017 at 12:36

5 Comments

I got your point, the mysql is just an example that I have given here so that anybody can execute it in commandline. I am looking for execution of a real commandline script which doesn't have any jdbc kind of libraries.. Thanks mate for the headsup.. I will edit my question to reflect the views.
I added a sample code for the first solution which may answer to your need.
it doesn'r trigger the select * query at all ..!
I added a full-java working example now. Hope it helps
That's a great thought, except writing it to a file.. I need the results as string.. cheers..! Thanks mate
0

I cannot test the exact commands you are executing but the problem may be that they actually don't stop executing and that is why your main process does not stop.

A workaround would be to:

  1. Use isAlive() to check whether these commands are still being executed (and kill these processes after some timeout).
  2. Use waitFor(long timeout, TimeUnit unit) method to make them terminate after a timeout. You could then check if the processes exited gracefully with exitValue() method.
answered May 26, 2017 at 12:15

1 Comment

I have updated the code with executable command, what will happen in this case, because the "mysql" commandline will openup msql commandline subprocess, then we have to execute the select * query.. how to do that ?

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.