I am seeing an odd problem when using an embedded Scala interpreter. It manifests itself as a corruption (?) of the hosting (non-interpreter) class loader. It roughly goes like this:
Foo
in the hosting environmentFoo
in some place (case f: Foo => ...
)IMain -> interpret
)Foo
fails; if I check the class it is Foo
but it does not match with Foo
So I except that there are now two competing class loaders which produce two non-identical instances of class Foo
. There is only one Foo
in my entire class path, so there is no way that it could be shadowed. Also, it is sufficient to run something like 1 + 1
in the interpreter, so there is absolutely no way that the IMain
itself tried to load class Foo
.
I know this is very vague, but I am hoping for hints as to trace the bug.
Edit: After further investigation, this problem occurs only when building against Scala 2.11.0, but disappears when building against 2.10.4; I ensured that the builds were made from clean-state. This worries me, because it could indicate a new problem with the 2.11 interpreter?
The class involved (Foo
in the example) is a Java class, so there is also no reason to believe it was compiled against the wrong Scala version.
Edit: After further investigation, this problem might relate to Java Swing rather than the Scala interpreter. Foo
is actually a javax.swing.text.Document
sub-class, and I can see some problems with JEditorPane
(How can I safely solve this Java context classloader problem?) and Swing threading (http://bugs.java.com/view_bug.do?bug_id=8017776). I am using OpenJDK 6 and OpenJDK 7, I believe OpenJDK 6 is a fork off OpenJDK 7, so it might still be the problem showing up in the Bug database.
It appears that in Scala 2.11.0, the interpreter sets the thread's context class loader but does not restore it to its previous value.
The following is a workaround:
val th = Thread.currentThread()
val cl = th.getContextClassLoader
try {
intp.interpret(text)
} finally {
th.setContextClassLoader(cl)
}