Java-программа зависает, когда ProcessBuilder выполняет сценарий с приглашением ввода - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть пакетный сценарий и скрипт оболочки, которые выполняют команду MYSQL.

mysql -u user -p < path\etc\script\db\dosomething.sql

У меня есть Java-программа, которая использует ProcessBuilder для выполнения пакетного сценария.Я знаю, что эта команда запросит у пользователя пароль, я также знаю, что я могу альтернативно использовать --password (который выдает небезопасное предупреждение) или файл конфигурации, чтобы установить параметры входа в систему.Я хочу предоставить пароль, используя приглашение ввода через ProcessBuilder, но когда я запускаю программу, она просто зависает, и я понятия не имею, почему.Когда я использую JVisualVM для просмотра того, что происходит, я замечаю, что поток OutputStream не запущен, и если он это сделал, то что зависает в программе?Ниже моя реализация: -

Класс, который имеет дело с InputStream и ErrorStream:

public static class InStream extends Thread {

    private final InputStream in;
    private final PrintWriter pw;

    public InStream(InputStream in, PrintWriter pw, String threadName) {
        super(threadName);
        this.in = in;
        this.pw = pw;
    }

    @Override
    public void run() {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(in));) {
            String line;
            while ((line = br.readLine()) != null) {
                if (Thread.currentThread().isInterrupted()) {
                    Thread.currentThread().interrupt();
                    break;
                }
                pw.println(line);
                pw.flush();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
}

Класс, который имеет дело с OutputStream:

public static class OutStream extends Thread {

    private final String message;
    private final OutputStream out;

    public OutStream(OutputStream out, String threadName, String message) {
        super(threadName);
        this.out = out;
        this.message = message;
    }

    @Override
    public void run() {
        try (PrintWriter pw = new PrintWriter(out);) {
            pw.println(message);
            pw.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Вот основнойПрограмма:

public static void main(String[] args) {
    try {
        String password = "Y0urp@ssw0rd";
        ProcessBuilder builder = new ProcessBuilder("path\\etc\\script\\cli\\batchWithSQLCommand.bat");
        Process process = builder.start();
        StringWriter errors = new StringWriter();
        StringWriter input = new StringWriter();
        new OutStream(process.getOutputStream(), "output-stream-thread", password).start();
        new InStream(process.getErrorStream(), new PrintWriter(errors, true), "error-stream-thread").start();
        new InStream(process.getInputStream(), new PrintWriter(input, true), "input-stream-thread").start();
        process.waitFor();
        System.out.println("inputStream: " + input.toString());
        System.out.println("Error Stream: " + errors.toString());
    } catch (IOException | InterruptedException ex) {
       //throw error here
    } catch (Error | Exception ex) {
         //throw error here
    }
}

В чем может быть проблема?

...