Hi,
I am developing a KNIME node for CMDock. The node just runs the CMDock program as subprocess with ProcessBuilder class. It works on Linux, but not on Windows.
The main code that is responsible for running the program can be seen here.
I also wrote a standalone java program, that just runs the program with ProcessBuilder and it works fine. I also noticed, that the program runs fine, if I run KNIME with eclipse debugger.
This makes me believe, that KNIME is probably missing some permissions on Windows for running the program.
Any help is very welcome,
Jakob Maležič
Code for standalone java program that works:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
class ProcessBuilderTest {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/C", "C:\\Users\\jakob\\Downloads\\cmdock-v0.2.0-win64\\bin\\cmdock.exe", "-h");
int exitCode = 0;
try {
Process process = builder.start();
StreamGobbler streamGobbler = new StreamGobbler(
process.getInputStream(),
process.getErrorStream(),
System.out::println,
System.out::println
);
Future<?> future = Executors.newSingleThreadExecutor()
.submit(streamGobbler);
process.waitFor(600, TimeUnit.SECONDS);
future.get(600, TimeUnit.SECONDS);
System.out.println("Finished.");
} catch (IOException exception) {
System.out.println(exception.getMessage());
}
}
private static class StreamGobbler implements Runnable {
private InputStream inputStream;
private InputStream errorStream;
private Consumer<String> inputConsumer;
private Consumer<String> errorConsumer;
public StreamGobbler(
InputStream inputStream,
InputStream errorStream,
Consumer<String> inputConsumer,
Consumer<String> errorConsumer) {
this.inputStream = inputStream;
this.errorStream = errorStream;
this.inputConsumer = inputConsumer;
this.errorConsumer = errorConsumer;
}
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(inputConsumer);
new BufferedReader(new InputStreamReader(errorStream)).lines().forEach(errorConsumer);
}
}
}
