I have a Java class. Its constructor calls ProcessBuilder
class to run an external problem (the complete class code provided below, I think there is nothing important in it for my question, but I give it just to illustrate and make my question less abstract).
My code works well, however, when everything is done, it doesn't stop. It seems logical to me, because the external process is still running. So I find the way how to stop it. As my class just starts it, I think there is no "link" between the class instance and the running external process, so if I destroy this object, the external process will still run. My question is: how can I kill that external process?
I'm sorry for a stupid question, it has to be answered somewhere, but I can't find it.
Thank you very much for your time!
public static class OptimizerMOEA extends ExternalProblem {
public static final String SEPARATOR = "\\s+"; //a space
public static final float LOWER_BOUND = 0.0;
public static final float UPPER_BOUND = 275000000*3;
public static final String CPP_EXE_NAME = "optimizer_moea";
public OptimizerMOEA() throws IOException{
super(CPP_EXE_NAME);
}
public OptimizerMOEA(String path) throws IOException{
super(path);
}
@Override
public String getName() {
return "OptimizerMOEA";
}
@Override
public int getNumberOfVariables() {
//!!! TODO: pass this value from C++ function to this class
return 6890;
}
@Override
public int getNumberOfObjectives() {
return 2;
}
@Override
public int getNumberOfConstraints() {
return 0;
}
@Override
public Solution newSolution() {
Solution solution = new Solution(getNumberOfVariables(),
getNumberOfObjectives());
for (int i = 0; i < getNumberOfVariables(); i++) {
solution.setVariable(i, new RealVariable(LOWER_BOUND, UPPER_BOUND));
}
return solution;
}
}//EOF OptimizerMOEA class
EDIT:
This is the constructor from the parent class I use:
/**
* Constructs an external problem using {@code new
* ProcessBuilder(command).start()}. If the command contains arguments,
* the arguments should be passed in as separate strings, such as
* <pre>
* new ExternalProblem("command", "arg1", "arg2");
* </pre>
*
* @param command a specified system command
* @throws IOException if an I/O error occured
*/
public ExternalProblem(String... command) throws IOException {
this(new ProcessBuilder(command).start());
}
And these are the others constructors. My Java class communicates with the external process via standard I/O. So the constructors using socket are given just for completeness.
Maybe using the constructor with a process in parameter would be a solution. In this case, I'm still interested if there is a way to solve the problem with the first constructor (just because I don't see it, find it an interesting question and am wondering in which case this constructor could be useful and why).
/**
* Constructs an external problem that connects to a remote process via
* sockets. The remote process should be instantiated and already
* listening to the designated port number prior to invoking this
* constructor.
*
* @param host the host name of the remote system; or {@code null} to use
* the local host
* @param port the port number
* @throws UnknownHostException if the IP address of the specified host
* could not be determined
* @throws IOException if an I/O error occurred
*/
public ExternalProblem(String host, int port) throws IOException,
UnknownHostException {
this(new Socket(host, port));
}
/**
* Constructs an external problem that connects to a remote process via
* sockets. The remote process should be instantiated and already
* listening to the designated port number prior to invoking this
* constructor.
*
* @param address the IP address of the remote system
* @param port the port number
* @throws IOException if an I/O error occurred
*/
public ExternalProblem(InetAddress address, int port) throws IOException {
this(new Socket(address, port));
}
/**
* Constructs an external problem using the specified socket.
*
* @param socket the socket used to send solutions to be evaluated
* @throws IOException if an I/O error occurred
*/
ExternalProblem(Socket socket) throws IOException {
this(socket.getInputStream(), socket.getOutputStream());
}
/**
* Constructs an external problem using the specified process.
*
* @param process the process used to evaluate solutions
*/
ExternalProblem(Process process) {
this(process.getInputStream(), process.getOutputStream());
RedirectStream.redirect(process.getErrorStream(), System.err);
}
/**
* Constructs an external problem using the specified input and output
* streams.
*
* @param input the input stream
* @param output the output stream
*/
ExternalProblem(InputStream input, OutputStream output) {
super();
reader = new BufferedReader(new InputStreamReader(input));
writer = new BufferedWriter(new OutputStreamWriter(output));
}