Saturday, 8 April 2017

Java start Node.js program immediately closes

I'm trying to make a Discord bot that has a Java FXML interface along with a Node.js program to make for an Audio playing bot.

When I try to open the process for Node.js inside Java I'm noticing that it instantly closes because when I try to write I get the IOException pipes are being closed. I am unsure why this happens because when I run node inside the command line the exact same way it stays open. Does anyone know why my process immediately closes?

Node.js communication class:

public class NodeCommunicationHandler {

private static final Logger LOG = Logger.getLogger(NodeCommunicationHandler.class.getName());

private Process nodeProcess;
private ExecutorService threadPool;
private ProcessHandlerTask callbackHandler;
private StringProperty callback;
private OutputStream writeStream;

/**
 *
 */
public NodeCommunicationHandler() {
    try {
        // Activate Node.js sub-process
        this.nodeProcess = new ProcessBuilder("cmd", "/c", "start", "node", "\"" + Reference.NODE_PROGRAM_LOCATION + "\"").start();

        // Initialize the stdout writing stream
        this.writeStream = this.nodeProcess.getOutputStream();

        // Initialize the stdin reader on the process
        this.callbackHandler = new ProcessHandlerTask(this.nodeProcess);

        // Bind the callback data from the process to the callback property
        this.callback = new SimpleStringProperty();
        this.callback.bind(this.callbackHandler.messageProperty());

        // Run the thread of the process callback handler
        this.threadPool = Executors.newFixedThreadPool(2);
        this.threadPool.submit(this.callbackHandler);
    } catch (IOException ex) {
        NodeCommunicationHandler.LOG.log(Level.SEVERE, null, ex);
    }
}

/**
 * Retrieve the internal process callback.
 *
 * @return The callback.
 */
public StringProperty getCallback() {
    return this.callback;
}

/**
 * Writes a string command to the Node.js process.
 *
 * @param command The command to write.
 */
public void write(String command) {
    try {
        this.writeStream.write(command.getBytes());
        this.writeStream.flush();
    } catch (IOException ex) {
        NodeCommunicationHandler.LOG.log(Level.SEVERE, null, ex);
    }
}

/**
 * Stop the Node.js process
 */
public void stop() {
    try {
        // Write the command STOP towards the node process to promptly exit the discord API.
        this.write("STOP");

        // Close the writing stream since STOP is the last command we have to write.
        this.writeStream.close();

        // Wait for the Node.js acknowledgement of the STOP issue.
        NodeProcessExitHandler exitCond = new NodeProcessExitHandler(this.callback);
        this.threadPool.submit(exitCond).get();

        // Unbind the callback listener.
        this.callback.unbind();

        // Stop the callback handler and let the thread finish.
        this.callbackHandler.stop();

        // Keep the process alive until the callback handler has been disconnected.
        this.threadPool.awaitTermination(10000, TimeUnit.MILLISECONDS);

        // Kill the subprocess since we know
        this.nodeProcess.destroy();
    } catch (IOException | InterruptedException | ExecutionException ex) {
        NodeCommunicationHandler.LOG.log(Level.SEVERE, null, ex);
    }
}
}

And my javascript program:

var stdin = process.openStdin();

stdin.addListener("data", function(d) {
    console.log("You entered: " + d.toString());
});

The javascript is really basic but it should be able to provide what I need.



via Thodor12

No comments:

Post a Comment