Как мне добавить информацию в STDERR, когда метод генерирует stderr? - PullRequest
1 голос
/ 23 июня 2009

Есть ли способ, которым я могу поймать, когда метод генерирует запись в STDERR? Я пытаюсь получить некоторую информацию перед каждой записью STDERR.

скажем, наш метод:

parser.thatGeneratesSTDERR();

это сгенерирует что-то вроде

Строка 37:29 нет жизнеспособной альтернативы для символа 'a'

могу я просто обернуть это чем-то, что ловит stderr, который нужно написать, и предваряет некоторые информация, поэтому она будет выглядеть так:

Файл: mybadfile.txt - строка 37:29 - нет подходящей альтернативы для символа 'a'

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

Я должен отметить, что этот метод не всегда генерирует STDERR - причина, по которой я пытаюсь их поймать, заключается в том, что он НЕ ДОЛЖЕН генерировать STDERR - но так как он вызывается для довольно многих файлов (более 40) Я никогда не знаю, какой файл генерирует сообщение об ошибке - поиск его занимает вечность.

UPDATE так что, да, мы можем изменить наш STDERR - я просто забыл, что мне нужно переопределить мой println в моем новом STDERR ... вот соответствующий код:

public static String errfile = "";

static {
  final PrintStream currentErr = System.err;
  PrintStream newErr = new PrintStream(currentErr)
  { 
    public void println(String string) {
      print("File: " + errfile + " --");
      print(string);
      super.println();
    }
  };

  System.setErr(newErr);
}

затем для каждого файла, который я тестирую, все, что мне нужно сделать, это заменить errfile на имя файла, и мой вывод получится ожидаемым ...

спасибо большое!

Ответы [ 3 ]

1 голос
/ 23 июня 2009

Я не уверен, будет ли это работать, учитывая, как работает System.setErr.

Я бы создал новый класс, который расширяет поток печати и перезаписывает методы для добавления вашего комментария. Затем установите поток ошибок для вашего нового printstream. Не вызывайте System.err.printxxx из этого нового класса.

ех ...

class PrependPrintStream extends PrintStream {

PrependPrintStream(PrintStream ps, String pre){...}
...
public void print(boolean b) {
super.print(this.pre);
super.print(b);
}
...

Я посмотрел в Sun PrintStream Impl, и похоже, что все printxxx делегат для записи (String), который является закрытым вместо защищенного. Я думаю, вы можете скопировать / вставить код.

EDIT ::

A намного Лучшее решение - использовать протоколирование вместо System.err. Это позволяет вам выключать и включать ваши операторы и позволяет вам создавать собственный обработчик ошибок. Ваш конкретный обработчик может добавить строку, которую вы хотите, к строке перед печатью в System.err. Это также имеет то преимущество, что только операторы, использующие ваш конкретный регистратор, будут иметь предварительно добавленный текст, а другие вызовы System.err - нет.

1 голос
/ 23 июня 2009

Похоже, вы, вероятно, хотите взглянуть на Аспектно-ориентированное программирование (AOP). Используя AOP, вы можете создать прокси для анализатора, которому вы звоните. Перед вызовом метода thatGeneratesSTDERR () вы можете сделать так, чтобы он вызывал ваш вызов. С вашего звонка вы можете выводить информацию, которую вы хотите.

Обратите внимание, что для понимания работы АОП может потребоваться некоторое чтение.

AspectJ - http://www.eclipse.org/aspectj/

АОП Альянс - http://sourceforge.net/projects/aopalliance

0 голосов
/ 23 июня 2009

Вы можете использовать System.setErr для перенаправления stderr на ваш собственный PrintStream.

...