PlayDependencyClassLoader找不到应用程序代码

时间:2014-05-26 23:11:33

标签: scala playframework playframework-2.0

当第三方依赖项尝试使用

加载Play应用程序中定义的类时
Class.forName(className, true, Thread.currentThread().getContextClassLoader());

Play将抛出ClassNotFoundException,因为上下文类加载器的类型为PlayDependencyClassLoader,显然只包含在jar依赖项中定义的类。

Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: eventstore.Commit
    at org.mapdb.SerializerPojo.classForName(SerializerPojo.java:96)
    at org.mapdb.SerializerPojo$1.deserialize(SerializerPojo.java:74)
    at org.mapdb.SerializerPojo$1.deserialize(SerializerPojo.java:39)

仅在使用play run启动播放时才会出现此情况。使用play start开始播放正确加载课程。

因为这种行为而牺牲班级热交换将是一种耻辱。有一个已知的解决方法吗?

2 个答案:

答案 0 :(得分:1)

Play HttpExecutionContext也可用于跨线程传播ClassLoader。如果设置了HttpExecutionContextHttp.Context也传播{{1}}线程本地。

请在此处查看我的回答:How to use Http.Context.current() in a Promise in Play?

另见Play issue #2847 – classloader issues when using "run"

答案 1 :(得分:0)

现在的hacky类型修复程序包含使用Class.forName的第三方库的调用,其函数如下:

  // see Play classloader bug https://github.com/playframework/playframework/issues/822
  def fixClassLoader[E](f: () => E) = {
    val old = Thread.currentThread().getContextClassLoader()
    try {
      Thread.currentThread().setContextClassLoader(Play.application.classloader)
      f()
    } finally {
      Thread.currentThread().setContextClassLoader(old)
    }
  }