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.
-
It should exit from the main process, show us the code.syntagma– syntagma2017年05月26日 12:06:43 +00:00Commented 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.peaceUser– peaceUser2017年05月26日 12:09:56 +00:00Commented May 26, 2017 at 12:09
3 Answers 3
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.)
2 Comments
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
5 Comments
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:
- Use
isAlive()to check whether these commands are still being executed (and kill these processes after some timeout). - Use
waitFor(long timeout, TimeUnit unit)method to make them terminate after a timeout. You could then check if the processes exited gracefully withexitValue()method.