在代码重新加载模式下运行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)
答案 0 :(得分:0)
此错误表示同一个类有2个实例,由不同的类加载器加载。这种行为植根于java:来自不同类加载器的类是不一样的。基本上equals类的方法是类名和类加载器的功能。在这种情况下,即使它们来自同一个jar或文件夹,类也不一样。
当容器重新加载代码时,它会创建一个新的类加载器,而你的会话仍然保存使用旧类加载器加载的flash map的实例。这很可能是问题的原因。
答案 1 :(得分:0)
在Java中,每个类都由其完全限定的类名和加载它的类加载器标识,这意味着:
ClassLoader1.my.package.MyClass != ClassLoader2.my.package.MyClass
这表明无法将MyClass
中加载的ClassLoader1
类对象转换为从MyClass
加载的ClassLoader2
类型。您可以在
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
另一方面,不可能在同一个类加载器中加载相同的类两次,所以你需要一个新的类加载器,没有办法解决它。虽然我从未编写过执行类重新加载的代码,但可以假设类重新加载在实践中意味着:
由于上面所描述的内容,在设计应该重新加载的类时需要小心:参见http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html#designing