Skip to content

Commit 313303a

Browse files
authored
support for setting the correct classloader on threadlocal when compiling snippets (#42)
1 parent 1c6876c commit 313303a

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

plugin/src/main/scala/eisner/EisnerPlugin.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ object EisnerPlugin extends AutoPlugin with ReflectionSupport with SnippetSuppor
4646
val dcp = (Compile / dependencyClasspath).value.map(_.data)
4747
val scp = (Compile / scalaInstance).value.allJars
4848

49+
// Let's capture the original classloader associated to the current thread
50+
val originalClassloader = Thread.currentThread.getContextClassLoader
51+
4952
val topologyDescriptions = eisnerTopologiesSnippet.value match {
5053
case None =>
5154
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
6871
// see https://stackoverflow.com/a/30251930
6972
Thread.currentThread.setContextClassLoader(classOf[PromiseException].getClassLoader)
7073

71-
if (topologyDescriptions.nonEmpty) {
74+
val result: Set[File] = if (topologyDescriptions.nonEmpty) {
7275
val config = Config(eisnerColorSubtopology.value, eisnerColorTopic.value, eisnerColorSink.value)
7376
val topologiesWithDots = topologyDescriptions
7477
.map {
@@ -102,6 +105,11 @@ object EisnerPlugin extends AutoPlugin with ReflectionSupport with SnippetSuppor
102105
log.warn("Eisner - No topology found!")
103106
Set.empty
104107
}
108+
109+
// re-set the current thread's classloader to what we captured at the start
110+
Thread.currentThread.setContextClassLoader(originalClassloader)
111+
112+
result
105113
}
106114
}
107115
}

plugin/src/main/scala/eisner/SnippetSupport.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ private[eisner] final class Compiler(bootClasspath: Seq[File], classpath: Seq[Fi
4040

4141
private[this] final def compile(code: String): Class[_] = {
4242
val name = className(code)
43+
44+
// external code we're compiling in the snippet may be relying on current thread's classloader
45+
// e.g. https://github.com/sksamuel/avro4s/blob/v3.0.5/avro4s-core/src/main/scala/com/sksamuel/avro4s/SchemaFor.scala#L323
46+
Thread.currentThread.setContextClassLoader(cl)
47+
4348
run.compileSources(new BatchSourceFile("(inline)", mkClass(name, code)) :: Nil)
4449
cl.loadClass(name)
4550
}

0 commit comments

Comments
 (0)