From 313303a0765db12c84cf18e063321cbfbb9c647d Mon Sep 17 00:00:00 2001 From: Julien Jean Paul Sirocchi Date: Mon, 13 Jan 2020 15:43:37 +0000 Subject: [PATCH] support for setting the correct classloader on threadlocal when compiling snippets (#42) --- plugin/src/main/scala/eisner/EisnerPlugin.scala | 10 +++++++++- plugin/src/main/scala/eisner/SnippetSupport.scala | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/plugin/src/main/scala/eisner/EisnerPlugin.scala b/plugin/src/main/scala/eisner/EisnerPlugin.scala index d8f1f59..ca8210c 100644 --- a/plugin/src/main/scala/eisner/EisnerPlugin.scala +++ b/plugin/src/main/scala/eisner/EisnerPlugin.scala @@ -46,6 +46,9 @@ object EisnerPlugin extends AutoPlugin with ReflectionSupport with SnippetSuppor val dcp = (Compile / dependencyClasspath).value.map(_.data) val scp = (Compile / scalaInstance).value.allJars + // Let's capture the original classloader associated to the current thread + val originalClassloader = Thread.currentThread.getContextClassLoader + val topologyDescriptions = eisnerTopologiesSnippet.value match { case None => val cp = dcp.filter(f => f.getName.contains("kafka") || f.getName.contains("slf4j")) :+ cd @@ -68,7 +71,7 @@ object EisnerPlugin extends AutoPlugin with ReflectionSupport with SnippetSuppor // see https://stackoverflow.com/a/30251930 Thread.currentThread.setContextClassLoader(classOf[PromiseException].getClassLoader) - if (topologyDescriptions.nonEmpty) { + val result: Set[File] = if (topologyDescriptions.nonEmpty) { val config = Config(eisnerColorSubtopology.value, eisnerColorTopic.value, eisnerColorSink.value) val topologiesWithDots = topologyDescriptions .map { @@ -102,6 +105,11 @@ object EisnerPlugin extends AutoPlugin with ReflectionSupport with SnippetSuppor log.warn("Eisner - No topology found!") Set.empty } + + // re-set the current thread's classloader to what we captured at the start + Thread.currentThread.setContextClassLoader(originalClassloader) + + result } } } diff --git a/plugin/src/main/scala/eisner/SnippetSupport.scala b/plugin/src/main/scala/eisner/SnippetSupport.scala index b93222e..5c31b36 100644 --- a/plugin/src/main/scala/eisner/SnippetSupport.scala +++ b/plugin/src/main/scala/eisner/SnippetSupport.scala @@ -40,6 +40,11 @@ private[eisner] final class Compiler(bootClasspath: Seq[File], classpath: Seq[Fi private[this] final def compile(code: String): Class[_] = { val name = className(code) + + // external code we're compiling in the snippet may be relying on current thread's classloader + // e.g. https://github.com/sksamuel/avro4s/blob/v3.0.5/avro4s-core/src/main/scala/com/sksamuel/avro4s/SchemaFor.scala#L323 + Thread.currentThread.setContextClassLoader(cl) + run.compileSources(new BatchSourceFile("(inline)", mkClass(name, code)) :: Nil) cl.loadClass(name) }