Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMain interpret does not reset context classloader #8521

Closed
scabug opened this issue Apr 21, 2014 · 9 comments

Comments

@scabug
Copy link

commented Apr 21, 2014

Calling interpret sets the current thread's context classloader, but fails to reset it to its previous state when returning from that method.

The following workaround illustrates the problem:

    val th = Thread.currentThread()
    val cl = th.getContextClassLoader
    try {
      imain.interpret(text)
    } finally {
      th.setContextClassLoader(cl)
    }

Jason Zaugg suggests that the following might be the regression: scala/scala@3a30af1#diff-36a995091016ecd5cdb97e267764e05aL538

@scabug

This comment has been minimized.

Copy link
Author

commented Apr 21, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8521?orig=1
Reporter: @Sciss
Affected Versions: 2.11.0

@scabug

This comment has been minimized.

Copy link
Author

commented Aug 5, 2014

@gourlaysama said:
I can't seem to be able to reproduce it...

$ cat test.scala
import scala.tools.nsc.interpreter.IMain

object Test extends App {
  val cl = Thread.currentThread().getContextClassLoader
  println(cl)

  val imain = new IMain()
  imain.interpret("println(42)")
 
  val cl2 = Thread.currentThread().getContextClassLoader
  println(cl2)

  println(cl == cl2)
}
$ scala Test
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@1f32e575
42
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@1f32e575
true
@scabug

This comment has been minimized.

Copy link
Author

commented May 15, 2015

Martin Grotzke (martin.grotzke) said (edited on May 15, 2015 10:12:49 PM UTC):
I'm also experiencing this with iMain.compile. Before iMain.compile the thread context CL is sun.misc.Launcher$AppClassLoader@368239c8 and afterwards it is scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@39094bde.

This happened in tests (scalatest), where in consequence other tests that try to create an ActorSystem fail because in akka some components are created via reflection relying on the thread context CL:

    sbt.ForkMain$ForkError: interface akka.actor.Scheduler is not assignable from class akka.actor.LightArrayRevolverScheduler
            at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:69)
            at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:66)
            at scala.util.Try$.apply(Try.scala:191)
            at akka.actor.ReflectiveDynamicAccess.getClassFor(DynamicAccess.scala:66)
            at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
            at akka.actor.ActorSystemImpl.createScheduler(ActorSystem.scala:676)
            at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:576)
            at akka.actor.ActorSystem$.apply(ActorSystem.scala:142)
            at akka.actor.ActorSystem$.apply(ActorSystem.scala:109)
            at foo.bar.SomeSpec.<init>(SomeSpec.scala:32)
            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:422)
            at java.lang.Class.newInstance(Class.java:442)
            at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:641)
            at sbt.ForkMain$Run$2.call(ForkMain.java:294)
            at sbt.ForkMain$Run$2.call(ForkMain.java:284)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)

I can reproduce this with this App run from sbt with runMain foo.Main:

package foo

import javax.script.ScriptEngineManager

object Main extends App {

  val ngine = new ScriptEngineManager().getEngineByName("scala")

  val iMain = ngine.asInstanceOf[scala.tools.nsc.interpreter.IMain]
  class Foo
  iMain.settings.embeddedDefaults[Foo]

  println(Thread.currentThread().getContextClassLoader)
  iMain.compile("val x = 1")
  println(Thread.currentThread().getContextClassLoader)

}

scala version is 2.11.6

@scabug

This comment has been minimized.

Copy link
Author

commented Jan 23, 2017

@som-snytt

This comment has been minimized.

Copy link

commented Jul 21, 2017

@som-snytt

This comment has been minimized.

Copy link

commented Sep 12, 2017

Another mode of suffering

https://gitter.im/scala/scala?at=59b75be4177fb9fe7eacd7f1

https://gist.github.com/cnestor/2c1658d67cf2997a5cc586c7fb0b7fb0

where log4j loads script engines. And then everything breaks.

@adriaanm adriaanm closed this Sep 21, 2017

@adriaanm adriaanm modified the milestones: Backlog, 2.12.4 Sep 21, 2017

@Sciss

This comment has been minimized.

Copy link

commented Dec 15, 2018

I was just bitten by this again in 2.13.0-M5. Thought the issue was solved. I don't really understand this merge. Is it only for Scala 2.12? In the meantime I will reinstall my patch in my IMain subclass like so

      // work-around for SI-8521 (Scala 2.11.0)
      override def interpret(line: String, synthetic: Boolean): Results.Result = {
        val th = Thread.currentThread()
        val cl = th.getContextClassLoader
        try {
          super.interpret(line, synthetic)
        } finally {
          th.setContextClassLoader(cl)
        }
      }

I think the issue should be re-opened and tagged 2.13.x?

Sciss added a commit to Sciss/ScalaColliderSwing that referenced this issue Dec 15, 2018
ran again into scala/bug#8521
we need to apply the work around for 2.13.0-M5 as well
Sciss added a commit to Sciss/ScalaInterpreterPane that referenced this issue Dec 15, 2018
ran again into scala/bug#8521
we need to apply the work around for 2.13.0-M5 as well
@som-snytt

This comment has been minimized.

Copy link

commented Dec 16, 2018

@Sciss yes, it was never forward-ported over the scary REPL refactor. I'll refresh my memory and make a PR. One really does take forward-merging for granted.

@lrytz

This comment has been minimized.

Copy link
Member

commented Dec 17, 2018

scala/scala#7544 for 2.13 (scala/scala#5657 for 2.12)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.