diff --git a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
index 1061407894..9c8b1e3e0c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
@@ -22,7 +22,9 @@
import ch.qos.logback.core.status.WarnStatus;
/**
- * Sets a skeleton implementation for appenders.
+ *
Sets a skeleton implementation for appenders.
+ *
+ *
It is coarsely synchronized in its {@link #doAppend(E)} method.
*
*
* For more information about this appender, please refer to the online manual
diff --git a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
index 3e20daf4f1..ccd6f56d62 100755
--- a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
@@ -77,9 +77,17 @@ public void start() {
addStatus(new ErrorStatus("No output stream set for the appender named \"" + name + "\".", this));
errors++;
}
+
+ if (encoder == null) {
+ addWarn("Encoder has not been set. Cannot invoke its init method.");
+ errors++;
+ }
+
+
// only error free appenders should be activated
if (errors == 0) {
super.start();
+ encoderInit();
}
}
@@ -164,12 +172,7 @@ public void setOutputStream(OutputStream outputStream) {
// close any previously opened output stream
closeOutputStream();
this.outputStream = outputStream;
- if (encoder == null) {
- addWarn("Encoder has not been set. Cannot invoke its init method.");
- return;
- }
- encoderInit();
} finally {
streamWriteLock.unlock();
}
@@ -198,8 +201,11 @@ private void writeBytes(byte[] byteArray) throws IOException {
return;
streamWriteLock.lock();
+
try {
- writeByteArrayToOutputStreamWithPossibleFlush(byteArray);
+ if(isStarted()) {
+ writeByteArrayToOutputStreamWithPossibleFlush(byteArray);
+ }
} finally {
streamWriteLock.unlock();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
index aa8ff2409b..79ea30e18b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
@@ -22,7 +22,7 @@
import ch.qos.logback.core.status.WarnStatus;
/**
- * Similar to AppenderBase except that derived appenders need to handle thread
+ * Similar to {@link AppenderBase} except that derived appenders need to handle thread
* synchronization on their own.
*
* @author Ceki Gülcü
@@ -30,7 +30,7 @@
*/
abstract public class UnsynchronizedAppenderBase extends ContextAwareBase implements Appender {
- protected boolean started = false;
+ protected volatile boolean started = false;
// using a ThreadLocal instead of a boolean add 75 nanoseconds per
// doAppend invocation. This is tolerable as doAppend takes at least a few
diff --git a/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
index 99281b6729..73f9d95f43 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
@@ -82,8 +82,8 @@ public void nullFileFooter() {
public void headerFooterCheck(String fileHeader, String presentationHeader, String presentationFooter,
String fileFooter) {
- OutputStreamAppender