commons-io Tailer не вызывает handle(), когда файл создается внутри JVM
У меня есть рабочая реализация Tailer ( commons-io Tailer) Вот мой Tailer:
public class SyslogConsumer implements TailerListener {
@Override
public void handle(String line) { System.out.println(line);}
...
}
public void process() {
TailerListener listener = new SyslogConsumer();
final Tailer tailer = Tailer.create( path.toFile(), listener );
Runtime.getRuntime().addShutdownHook( new Thread( "LogProcessor shutdown hook" ) {
public void run() {
tailer.stop();
}
} );
}
и мой тест:
public class LogProcessorTest {
private static Path templog;
private static final String logEvent = "May 1 00:00:00 this is valid";
@Before
public void setup()
throws IOException
{
templog = Files.createTempFile( "logprocessing", ".log" );
templog.toFile().deleteOnExit();
BufferedWriter bw = new BufferedWriter( new FileWriter( templog.toFile() ) );
bw.write( logEvent );
bw.newLine();
bw.close();
}
@Test
public void testProcessingValidEntriesProducesEvents()
throws IOException
{
// utility method that pipes stdout to my bytearray
ByteArrayOutputStream bos = new ByteArrayOutputStream();
TestUtils.captureStdOut( bos );
LogProcessor proc = new LogProcessor( templog.toString() );
proc.process();
String s = bos.toString( "UTF-8" );
Assert.assertEquals( logEvent, s );
}
}
В тот момент, когда bos проверяется на предмет его содержимого, он пуст, но файл журнала содержит 2 строки:
>May 1 00:00:01 this is valid
>
Если я укажу свой тест на файл, который создан и записан с использованием скрипта bash:
$ cat test/endlessLogGenerator.sh
#! /bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
out="$DIR/data/logstream.out"
echo > $out
c=0
while :
do
let c=$((c+1))
echo $(date +"%b %d %T this is message $c") >> $out
sleep 1
done
тогда это работает отлично. Тем не менее, когда я создаю файл в тестовом средстве, мой обработчик никогда не вызывает обработчик Tailer. Я попытался создать свой файл в отдельном потоке, также попытался записать в существующий файл, не созданный тестом, также попытался записать файл в моем тесте после передачи его Tailer для просмотра и т. Д. Ничего не работает. Ничто из того, что я пытаюсь записать в файл в тестовом средстве, не заставит TailerListener запустить метод handle(). Я запускаю это на Windows 7 с Java 8, внутри Eclipse. У кого-нибудь есть опыт модульного тестирования метода handle() TailerListener с файлом, записанным JVM, выполняющей тест?
Благодарю.
1 ответ
Оказывается, моя проблема была вызвана тем, что Tailer проглотил исключение и тихо закрыл поток:
Tailer's run() implementation...
....
} catch (Exception e) {
listener.handle(e);
} finally {
IOUtils.closeQuietly(reader);
}
....
В моей реализации handle() я анализировал дату из журнала, и DateTimeFormatter не был настроен с правильным шаблоном, поэтому он генерировал непроверенное исключение времени выполнения, которое было поймано Tailer. Странный выбор разработчиков библиотеки для разработки этого поведения.
Я держу вопрос вместо того, чтобы просто удалить его, потому что это предостережение может пригодиться.