Как остановить утечку javaw-процессов при запуске jRuby в потоке? - PullRequest
1 голос
/ 20 августа 2011

Я пропускаю процессы jRuby, и я не знаю, как это остановить.Мне нужен скрипт groovy, чтобы продолжить работу после запуска jRuby, и мне нужно, чтобы jRuby умер, когда умирает основной скрипт.1008 *

while( true )
   puts 'Hello from jRuby'
   sleep 1
end

test.groovy

def command = "jruby ./loop.rb"
Thread.start {
    Process process
    try {
        process = command.execute()
    }
    catch (IOException e) {
        e.printStackTrace()
        return
    }

    Runtime.runtime.addShutdownHook {
        println "Attempting to stop process"
        process.destroy()
    }

    process.consumeProcessOutput(System.out, System.err)
    process.waitFor()
}

while( true ){ println 'Hello from groovy'; Thread.sleep(1000) }

Выполнить groovy test.groovy

Как убедитьсячто внешний javaw процесс, который я создаю с помощью jRuby, убит?Даже если отправка Cntrl+C в работающее приложение убивает запущенный процесс groovy, процесс jRuby остается на месте.Помощь

1 Ответ

0 голосов
/ 21 августа 2011

Это должно сработать, но это уродливо:

Основное решение - посмотреть на вывод jps -lm и завершить соответствующий процесс из перечисленных там PID.

new JavaProcessKiller().killAll('loop.rb')

class JavaProcessKiller {
    public void killAll(String processPattern) {
        getRunningJavaProcesses().each { String processLine ->
            if (processLine.contains(processPattern)) {
                String pidToKill = getPidFromProcessLine(processLine)
                killPid(pidToKill)
            }
        }
    }

    protected String[] getRunningJavaProcesses() {
        def output = new ByteArrayOutputStream()
        def p = ['jps', '-lm'].execute()
        p.consumeProcessOutput(new PrintStream(output), System.err)
        p.waitFor()
        return output.toString().split("\\n")
    }

    protected String getPidFromProcessLine(String line) {
        def pidPattern = /^(\d+).*$/
        def matcher = (line =~ pidPattern)
        return matcher[0][1]
    }

    protected void killPid(String pid) {
        def killCommands = [
                ['taskkill', '/F', '/PID', pid],
                ['kill', pid]
        ]

        boolean processKilledSuccessfully = false
        killCommands.each { command ->
            if (!processKilledSuccessfully) {
                try {
                    def output = new ByteArrayOutputStream()
                    def error = new ByteArrayOutputStream()
                    def process = command.execute()
                    process.consumeProcessOutput(new PrintStream(output), new PrintStream(error))
                    process.waitFor()
                    processKilledSuccessfully = true
                }
                catch (Exception e) {
                }
            }
        }
    }
}
...