捕获Java中特定线程的控制台输出

Ale*_*ley 2 java console multithreading

我意识到在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要的只是一些代码,或者一个关于如何获取的答案的链接,捕获被调用方法的System.out和System.err输出.任何人可以给予的帮助将不胜感激.

提前致谢!

编辑:这不仅仅用于测试,最终将投入生产.

编辑2:这需要是线程安全的.其他线程可能同时调用多个主要方法,我希望每个线程只捕获自己的特定输出.

Zar*_*nen 5

使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建和使用此流

HackedPrintStream hps = new HackedPrintStream(System.out);
System.setOut(hps);
Run Code Online (Sandbox Code Playgroud)

我真的建议你努力寻找另一个解决方案,因为这不是很好.