Захватите консольный вывод определенного потока в Java - PullRequest
2 голосов
/ 12 апреля 2009

Я понимаю, что есть похожие вопросы по SO, но они не совсем решают мою проблему.

Мне бы хотелось, чтобы метод, который, учитывая объект Class, вызывал метод "main", то есть public static void main, для этого класса (если он существует) и захватывал вывод консоли этого метода main. , Класс, выполняющий вызов, не является потоком демона.

У меня уже есть часть кода, но я не уверен, как захватить вывод консоли, и, кроме того, как захватить его только для * этого конкретного потока. Вот что у меня есть:

public class Output extends Thread {
    private Class testClass;

    public Output(Class clazz) {
        this.testClass = clazz;
    }

    private Method getMainMethod(Class clazz) {
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (isMainMethod(method)) { 
                return method;
            }
        }

        return null;
    }

    private Boolean isMainMethod(Method method) {
        return (method.getName().equals("main") &&
                Modifier.isStatic(method.getModifiers()) &&
                method.getReturnType().equals(Void.class));
    }

    public void run() {
        Method mainMethod = null;

        if ((mainMethod = getMainMethod(this.testClass)) == null) {
            //if there's no static void main method, throw exception
            throw new YouFuckedItUpException();
        }

        mainMethod.invoke(this.testClass, new String[0]);

        return heresWhereImStuckIWantToCaptureTheConsoleOutputAndReturnIt();
    }
}

Все, что мне нужно, это некоторый код или ссылка на ответ о том, как захватить выходные данные System.out и System.err вызываемого метода. Буду очень признателен за любую помощь.

Заранее спасибо!

РЕДАКТИРОВАТЬ: Это не только для тестирования, это в конечном итоге будет что-то запущено в производство.

РЕДАКТИРОВАТЬ 2 : Это должно быть поточно-ориентированным. Несколько основных методов будут вызываться другими потоками, возможно, в одно и то же время, и я хочу, чтобы каждый поток записывал только свой собственный конкретный вывод.

Ответы [ 3 ]

5 голосов
/ 12 апреля 2009

Используйте System.setOut , а затем напишите подкласс printstream, который переопределяет все методы печати / записи и регистрирует данные, если они поступают из потока, который вы хотите отслеживать.

псевдокод:

public class HackedPrintStream extends PrintStream {
    private PrintStream originalStream;
    private HashMap<Thread, PrintStream> loggerStreams = new HashMap<Thread, PrintStream>();

    public HackedPrintStream(PrintStream originalStream) {
        this.originalStream = originalStream;
    }

    public synchronized void logForThread(Thread threadToLogFor, PrintStream streamToLogTo) {
        loggerStreams.put(threadToLogFor, streamToLogTo);
    }

    /** example overridden print method, you need to override all */
    public synchronized void println(String ln) {
        PrintStream logPS = loggerStreams.get(Thread.currentThread());
        if (logPS != null) { logPS.println(ln); }
        originalStream.println(ln);
    }
}

Затем вы можете создать и использовать этот поток с

HackedPrintStream hps = new HackedPrintStream(System.out);
System.setOut(hps);

Я бы действительно посоветовал вам поискать другое решение, поскольку это не очень красиво.

2 голосов
/ 12 апреля 2009

Поскольку вы используете метод main() - нужен ли он для того же процесса? Если нет, вы можете попытаться создать его как новый процесс (java.lang.Process).

Класс Process предоставляет необходимые методы для захвата StdOut, StdErr и / или StdIn.

Примечание Поскольку все работает в своем собственном процессе, проблем с безопасностью потоков не должно быть. Однако вам все равно придется найти местоположение, в котором находится файл .class (или, по крайней мере, корневой каталог), чтобы вы могли запустить / создать Процесс с помощью java here.goes.your.ClassName.

0 голосов
/ 12 апреля 2009

Вы можете использовать System.setOut () и System.setErr (), но, конечно, выходные данные также будут записываться для остальной части программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...