【问题标题】:Class re-appears in a class loader after using embedded interpreter使用嵌入式解释器后类重新出现在类加载器中
【发布时间】:2014-04-21 11:55:44
【问题描述】:

我在使用嵌入式 Scala 解释器时发现了一个奇怪的问题。它表现为宿主(非解释器)类加载器的损坏(?)。大致是这样的:

  • 我在托管环境中有一个班级Foo
  • 我在某个地方匹配 Foo (case f: Foo => ...)
  • 我在某个时候运行解释器 (IMain -> interpret)
  • 之后Foo 的模式匹配失败;如果我检查课程是Foo,但它与Foo 不匹配

所以我除了现在有两个相互竞争的类加载器,它们会生成两个不相同的 class Foo 实例。在我的整个类路径中只有一个 Foo,所以它不可能被遮蔽。此外,在解释器中运行类似1 + 1 的东西就足够了,所以IMain 本身绝对不可能尝试加载类Foo

我知道这很模糊,但我希望能提供一些提示来追踪错误。


编辑:经过进一步调查,此问题仅在针对 Scala 2.11.0 构建时出现,但在针对 2.10.4 构建时消失;我确保构建是从干净状态进行的。这让我很担心,因为它可能表明 2.11 解释器出现了新问题?

所涉及的类(示例中为Foo)是一个Java 类,因此也没有理由相信它是针对错误的Scala 版本编译的。


编辑:经过进一步调查,这个问题可能与 Java Swing 而不是 Scala 解释器有关。 Foo 实际上是javax.swing.text.Document 的子类,我可以看到JEditorPane (How can I safely solve this Java context classloader problem?) 和Swing 线程(http://bugs.java.com/view_bug.do?bug_id=8017776) 的一些问题。我正在使用 OpenJDK 6 和 OpenJDK 7,我相信 OpenJDK 6 是 OpenJDK 7 的一个分支,所以它可能仍然是 Bug 数据库中出现的问题。

【问题讨论】:

    标签: swing scala classloader interpreter


    【解决方案1】:

    似乎在 Scala 2.11.0 中,解释器设置了线程的上下文类加载器,但没有将其恢复为之前的值。

    以下是一种解决方法:

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

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 2015-02-16
      • 2018-04-24
      • 2017-01-07
      • 2011-12-06
      • 1970-01-01
      • 2016-11-15
      • 2012-01-03
      相关资源
      最近更新 更多