Skip to content

Commit

Permalink
support for setting the correct classloader on threadlocal when compi…
Browse files Browse the repository at this point in the history
…ling snippets (#42)
  • Loading branch information
sirocchj authored Jan 13, 2020
1 parent 1c6876c commit 313303a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
10 changes: 9 additions & 1 deletion plugin/src/main/scala/eisner/EisnerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
}
}
5 changes: 5 additions & 0 deletions plugin/src/main/scala/eisner/SnippetSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 313303a

Please sign in to comment.