[
http://jira.qos.ch/browse/LBCORE-143?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11617#action_11617
]
Ceki Gulcu commented on LBCORE-143:
-----------------------------------
Hello Tom,
Thank you for this patch. I was not aware that Junit captured the console. What
does Junit do with the console after capturing it?
> ConsoleAppender should always write to current System.out / System.err. The
> underlying outputstream should not be bind statically.
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: LBCORE-143
> URL: http://jira.qos.ch/browse/LBCORE-143
> Project: logback-core
> Issue Type: Bug
> Components: Appender
> Affects Versions: 0.9.18
> Reporter: tomliliu
> Assignee: Logback dev list
> Attachments: ConsoleAppender.java
>
>
> Hi logback-dev,
> ConsoleAppender does not work nicely with JUnit.
> Symptom: when running junit tests with logback (default configuration, no
> logback configuration is provided), only the first test case's output was
> captured, the subsequent test cases' output were not captured by junit.
> The problem is that console appender binds itself to stdout / stderr
> statically.
> Illustrate what happens:
> Junit run test 1 -> System.out is set to test1.out -> Logback auto configure
> -> Console appender is bind to System.out, which is test1.out
> Junit run test 2 -> System.out is set to test2.out -> Console appender is
> still bind to test1.out -> The output of subsequent test cases are not
> correctly redirected.
> The ConsoleAppender's behavior is not correct as it should always write to
> current System.out / System.err.
> I worked out a simple fix and hope it will be useful:
> /**
> * Logback: the generic, reliable, fast and flexible logging framework.
> *
> * Copyright (C) 2000-2009, QOS.ch
> *
> * This library is free software, you can redistribute it and/or modify it
> under
> * the terms of the GNU Lesser General Public License as published by the Free
> * Software Foundation.
> */
> package ch.qos.logback.core;
> import java.io.IOException;
> import java.io.OutputStream;
> import ch.qos.logback.core.status.Status;
> import ch.qos.logback.core.status.WarnStatus;
> /**
> * ConsoleAppender appends log events to <code>System.out</code> or
> <code>System.err</code> using a layout specified by
> * the user. The default target is <code>System.out</code>.
> *
> * For more information about this appender, please refer to the online
> manual at
> * http://logback.qos.ch/manual/appenders.html#ConsoleAppender
> *
> * @author Ceki Gülcü
> */
> public class ConsoleAppender<E> extends WriterAppender<E> {
> public static final String SYSTEM_OUT = "System.out";
> public static final String SYSTEM_ERR = "System.err";
>
> protected String target = SYSTEM_OUT;
> private interface OutputStreamProvider {
> OutputStream getOutputStream();
> }
>
> private static class SysoutProvider implements OutputStreamProvider {
> @Override
> public OutputStream getOutputStream() {
> return System.out;
> }
> }
>
> private static class SyserrProvider implements OutputStreamProvider {
> @Override
> public OutputStream getOutputStream() {
> return System.err;
> }
> }
>
> private static class WrapperOutputStream extends OutputStream {
>
> private final OutputStreamProvider provider;
> WrapperOutputStream(OutputStreamProvider provider) {
> this.provider = provider;
> }
>
> @Override
> public void write(int b) throws IOException {
> provider.getOutputStream().write(b);
> }
> @Override
> public void write(byte[] b, int off, int len) throws IOException {
> provider.getOutputStream().write(b, off, len);
> }
> @Override
> public void write(byte[] b) throws IOException {
> provider.getOutputStream().write(b);
> }
> @Override
> public void close() throws IOException {
> provider.getOutputStream().close();
> }
> @Override
> public void flush() throws IOException {
> provider.getOutputStream().flush();
> }
> }
> /**
> * As in most logback components, the default constructor does nothing.
> */
> public ConsoleAppender() {
> }
> /**
> * Sets the value of the <b>Target</b> option. Recognized values are
> "System.out" and "System.err". Any other value
> * will be ignored.
> */
> public void setTarget(String value) {
> String v = value.trim();
> if (SYSTEM_OUT.equalsIgnoreCase(v)) {
> target = SYSTEM_OUT;
> } else if (SYSTEM_ERR.equalsIgnoreCase(v)) {
> target = SYSTEM_ERR;
> } else {
> targetWarn(value);
> }
> }
> /**
> * Returns the current value of the <b>Target</b> property. The default
> value of the option is "System.out".
> *
> * See also {...@link #setTarget}.
> */
> public String getTarget() {
> return target;
> }
> void targetWarn(String val) {
> Status status = new WarnStatus("[" + val + " should be System.out or
> System.err.", this);
> status.add(new WarnStatus("Using previously set target, System.out by
> default.", this));
> addStatus(status);
> }
> public void start() {
> if (target.equals(SYSTEM_OUT)) {
> setWriter(createWriter(new WrapperOutputStream(new
> SysoutProvider())));
> } else {
> setWriter(createWriter(new WrapperOutputStream(new
> SyserrProvider())));
> }
> super.start();
> }
> /**
> * This method overrides the parent {...@link WriterAppender#closeWriter}
> implementation because the console stream is
> * not ours to close.
> */
> protected final void closeWriter() {
> writeFooter();
> }
> }
>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
_______________________________________________
logback-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/logback-dev