0

在代码重新加载模式下运行 Scalatra 时,如果我在 scalate 引擎重新初始化之前加载页面,我会收到 500 错误。

如果我观察终端直到它看起来引擎已经完全重新加载,它工作正常,但我认为当我在 a) 成功编译和 b) 容器重启之间加载页面时会发生这种情况。

在我更改其他内容并强制进行新的编译和代码重新加载之前,这不会自行纠正。

我似乎无法找到为什么会这样,有没有人有任何想法?

这是我如何重新加载代码:

./sbt "container:start" "~ ;copy-resources;aux-compile"

这是我看到的错误:

HTTP ERROR 500

Problem accessing /. Reason:

    org.scalatra.FlashMap cannot be cast to org.scalatra.FlashMap
Caused by:

java.lang.ClassCastException: org.scalatra.FlashMap cannot be cast to org.scalatra.FlashMap
    at org.scalatra.FlashMapSupport$$anonfun$org$scalatra$FlashMapSupport$$getFlash$2$$anonfun$1.apply(flashMap.scala:182)
    at org.scalatra.FlashMapSupport$$anonfun$org$scalatra$FlashMapSupport$$getFlash$2$$anonfun$1.apply(flashMap.scala:182)
    at scala.Option.map(Option.scala:145)
    at org.scalatra.FlashMapSupport$$anonfun$org$scalatra$FlashMapSupport$$getFlash$2.apply(flashMap.scala:181)
    at org.scalatra.FlashMapSupport$$anonfun$org$scalatra$FlashMapSupport$$getFlash$2.apply(flashMap.scala:180)
    at scala.Option.getOrElse(Option.scala:120)
    at org.scalatra.FlashMapSupport$class.org$scalatra$FlashMapSupport$$getFlash(flashMap.scala:180)
    at org.scalatra.FlashMapSupport$class.flash(flashMap.scala:192)
    at beekeeper.controllers.HomeServlet.flash(HomeServlet.scala:13)
    at org.scalatra.FlashMapSupport$$anonfun$handle$1.apply$mcV$sp(flashMap.scala:137)
    at org.scalatra.FlashMapSupport$$anonfun$handle$1.apply(flashMap.scala:136)
    at org.scalatra.FlashMapSupport$$anonfun$handle$1.apply(flashMap.scala:136)
    at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
    at org.scalatra.DynamicScope$class.withRequest(DynamicScope.scala:71)
    at org.scalatra.ScalatraServlet.withRequest(ScalatraServlet.scala:49)
    at org.scalatra.FlashMapSupport$class.handle(flashMap.scala:136)
    at beekeeper.controllers.HomeServlet.handle(HomeServlet.scala:13)
    at org.scalatra.ScalatraServlet.service(ScalatraServlet.scala:54)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:560)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1072)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:382)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1006)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:365)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:485)
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:926)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:988)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:635)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:744)
4

2 回答 2

0

此错误表示同一类的 2 个实例由不同的类加载器加载。这种行为植根于java:来自不同类加载器的类是不一样的。基本上等于类的方法是类名和类加载器的功能。在这种情况下,即使它们来自同一个 jar 或文件夹,类也不相同。

当容器重新加载代码时,它会创建一个新的类加载器,而您的会话仍然保存使用旧类加载器加载的闪存映射实例。这很可能是问题的原因。

于 2014-08-06T00:53:33.663 回答
0

在 Java 中,每个类都由其完全限定的类名加载它的类加载器标识,这意味着:

ClassLoader1.my.package.MyClass != ClassLoader2.my.package.MyClass

这意味着不可能将加载的类的对象转换为从MyClass加载的ClassLoader1类型。您可以在以下位置找到更多详细信息MyClassClassLoader2

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

另一方面,不可能在同一个类加载器中两次加载同一个类,所以你需要一个新的类加载器,没有办法绕过它。虽然我从未编写过执行类重载的代码,但可以假设类重载在实践中意味着:

  • 创建一个新的类加载器
  • 重新加载类
  • 交换类加载器

由于上述原因,在设计应该重新加载的类时需要小心:请参阅http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html#designing

于 2014-08-22T09:00:59.537 回答