Я создал swing ui и перенаправил System.out и System.err в текстовое поле с этим кодом
ConsoleOutputStream cos = new ConsoleOutputStream(textColor, printStream);
System.setOut( new PrintStream(cos, true) );
ConsoleOutputStream расширяет ByteArrayOutputStream, и пока ничего не выполняется в новых потоках, это работает так, как ожидалось.
Однако мое приложение выполняет сторонние файлы jar, которые, в свою очередь, создают новые потоки. Когда эти потоки печатаются на System.out, он печатается в терминале, который запускал мое приложение, а не в текстовом поле. Я просмотрел эту ссылку: http://maiaco.com/articles/java/threadOut.php, но я не уверен, что это применимо к моей проблеме, поскольку у меня нет никакого контроля над потоками. Насколько известно моему приложению, не создаются нити (кроме основного потока gui).
Есть ли способ перенаправить все System.out: s и System.err: s независимо от потоков? Если нет, могу ли я слушать вызовы в System.out, а затем распечатать их в текстовое поле? Могу ли я прослушивать терминал, чтобы я запустил приложение и перенаправил весь вывод из него в мое приложение?
System.out
не зависит от потока. Есть две возможности:
Библиотеки читают System.out
прежде чем перенаправить его и кешировать значение. Исправление заключается в перенаправлении System.out
перед вызовом кода сторонней библиотеки.
Библиотеки не используют System.out
. Для записи на консоль есть альтернативы, такие как создание new FileOutputStream(FileDescriptor.out)
и запись на него. Или с помощью System.console()
.
Если это происходит через один из известных API протоколирования, вы можете переопределить поведение, удалив обработчик журнала консоли по умолчанию и установив собственный. В противном случае его довольно сложно сделать. Вам нужно будет изучить библиотеки и их API, чтобы узнать, как это сделать. Каждая сложная библиотека предложит способ записи сообщений непосредственно на консоль, не предлагая альтернативы - это действительно плохой стиль программирования, особенно для библиотеки.
Очень вероятно, что библиотеки, которые вы используете, используют API протоколирования.