Fix casting error during initialization

While running scripted, you see

```
ERROR StatusLogger Unable to create custom ContextSelector. Falling back to default.
 java.lang.ClassCastException: Cannot cast org.apache.logging.log4j.core.async.AsyncLoggerContextSelector to org.apache.logging.log4j.core.selector.ContextSelector
	at java.lang.Class.cast(Class.java:3369)
	at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(LoaderUtil.java:201)
	at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOfProperty(LoaderUtil.java:226)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.createContextSelector(Log4jContextFactory.java:97)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:58)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:94)
	at org.apache.logging.log4j.spi.ThreadContextMapFactory.createThreadContextMap(ThreadContextMapFactory.java:73)
	at org.apache.logging.log4j.ThreadContext.init(ThreadContext.java:223)
	at org.apache.logging.log4j.ThreadContext.<clinit>(ThreadContext.java:202)
	at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createDefaultInjector(ContextDataInjectorFactory.java:83)
	at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createInjector(ContextDataInjectorFactory.java:67)
	at org.apache.logging.log4j.core.lookup.ContextMapLookup.<init>(ContextMapLookup.java:34)
	at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:117)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:125)
	at org.apache.logging.log4j.core.config.DefaultConfiguration.<init>(DefaultConfiguration.java:46)
	at org.apache.logging.log4j.core.layout.PatternLayout$Builder.build(PatternLayout.java:650)
	at org.apache.logging.log4j.core.layout.PatternLayout.createDefaultLayout(PatternLayout.java:487)
	at sbt.internal.util.ConsoleAppender.<init>(ConsoleAppender.scala:245)
```

This aims to workaround the casting error during PatternLayout.createDefaultLayout()
that was originally used for ConsoleAppender.
The stacktrace shows it's having issue initializing default DefaultConfiguration.
Since we currently do not use Layout inside ConsoleAppender, the actual pattern is not relevant.
This commit is contained in:
Eugene Yokota 2017-07-13 20:20:49 -04:00
parent 88395e18a4
commit 19b3e47972
2 changed files with 18 additions and 5 deletions

View File

@ -8,7 +8,6 @@ import org.apache.logging.log4j.{ Level => XLevel }
import org.apache.logging.log4j.message.{ Message, ObjectMessage, ReusableObjectMessage }
import org.apache.logging.log4j.core.{ LogEvent => XLogEvent }
import org.apache.logging.log4j.core.appender.AbstractAppender
import org.apache.logging.log4j.core.layout.PatternLayout
import ConsoleAppender._
@ -242,7 +241,7 @@ class ConsoleAppender private[ConsoleAppender] (
val ansiCodesSupported: Boolean,
val useColor: Boolean,
val suppressedMessage: SuppressedTraceContext => Option[String]
) extends AbstractAppender(name, null, PatternLayout.createDefaultLayout(), true) {
) extends AbstractAppender(name, null, LogExchange.dummyLayout, true) {
import scala.Console.{ BLUE, GREEN, RED, RESET, YELLOW }
def append(event: XLogEvent): Unit =

View File

@ -5,6 +5,7 @@ import org.apache.logging.log4j.{ LogManager => XLogManager, Level => XLevel }
import org.apache.logging.log4j.core._
import org.apache.logging.log4j.core.appender.AsyncAppender
import org.apache.logging.log4j.core.config.{ AppenderRef, LoggerConfig }
import org.apache.logging.log4j.core.layout.PatternLayout
import scala.collection.JavaConverters._
import scala.collection.concurrent
import sjsonnew.JsonFormat
@ -47,6 +48,22 @@ sealed abstract class LogExchange {
val config = ctx.getConfiguration
config.getLoggerConfig(loggerName)
}
// This is a dummy layout to avoid casting error during PatternLayout.createDefaultLayout()
// that was originally used for ConsoleAppender.
// The stacktrace shows it's having issue initializing default DefaultConfiguration.
// Since we currently do not use Layout inside ConsoleAppender, the actual pattern is not relevant.
private[sbt] lazy val dummyLayout: PatternLayout = {
val _ = context
val ctx = XLogManager.getContext(false) match { case x: LoggerContext => x }
val config = ctx.getConfiguration
val lo = PatternLayout.newBuilder
.withConfiguration(config)
.withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
.build
lo
}
def jsonCodec[A](tag: String): Option[JsonFormat[A]] =
jsonCodecs.get(tag) map { _.asInstanceOf[JsonFormat[A]] }
def hasJsonCodec(tag: String): Boolean =
@ -63,9 +80,6 @@ sealed abstract class LogExchange {
private[sbt] def buildAsyncStdout: AsyncAppender = {
val ctx = XLogManager.getContext(false) match { case x: LoggerContext => x }
val config = ctx.getConfiguration
// val layout = PatternLayout.newBuilder
// .withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
// .build
val appender = ConsoleAppender("Stdout")
// CustomConsoleAppenderImpl.createAppender("Stdout", layout, null, null)
appender.start