[英]“VerifyError: Expecting a stackmap frame” using Play Framework and Google App Engine
I have a Google App Engine
webapp running with Play Framework 1.2.X
. 我有一个运行
Play Framework 1.2.X
的Google App Engine
应用Google App Engine
。 After Google changed their requirement to the webapp being built with Java 7
I have been struggling with a few different instances of VerifyError in the code. Google将其要求更改为使用
Java 7
构建的Webapp后,我一直在代码中遇到几个不同的VerifyError实例的问题。 I've been able to work around a few, but there is one that I can't seem to get around. 我已经能够解决一些问题,但是有一个我似乎无法解决。 When running I get a stacktrace (see far below).
运行时,我得到一个堆栈跟踪(请参阅下文)。
I think the problem occurs because of byte manipulation by Play Framework
using Javassist
. 我认为出现此问题是由于
Play Framework
使用Javassist
进行字节操作。 I see that others with related problems are able to get around it by using -XX:-UseSplitVerifier
as argument to the VM, but that doesn't seem to be an option on Google App Engine
. 我看到其他有相关问题的人可以通过使用
-XX:-UseSplitVerifier
作为VM的参数来解决此问题,但这似乎不是Google App Engine
的选项。
I have tried with newer releases of Javassist
and even using their master, but the problem is still the same. 我尝试使用
Javassist
较新版本,甚至使用它们的master进行尝试,但问题仍然相同。
I would file a bug report to Javassist
if I knew how Play Framework
was doing their magic and in more details how the problems occurs. 如果我知道
Play Framework
是如何Play Framework
并且更详细地说明问题是如何发生的,我将向Javassist
提交错误报告。 It seems like the problem happens because of how some of the if tests in the class play.data.validation.Validation
are structured, but that is really more of a guess then something I know. 由于类
play.data.validation.Validation
中的某些if测试是如何构建的,因此似乎出现了问题,但这实际上只是一个猜测,而我知道的东西。
Google App Engine
have this form where one can ask to be allowed to continue to use Java 6 for a while, but I haven't got any response on my two inquires. Google App Engine
具有这种形式,可以要求允许它继续使用Java 6一段时间,但是我的两次询问都没有得到任何回应。
Now I'm really blank and don't know how to solve this. 现在我真的很空白,不知道如何解决这个问题。 I'm in need of updating my webapp and would like to not have to rewrite the whole thing to do this (though I seem to have to do that in the longer run anyways).
我需要更新我的Web应用程序,并且不想重写整个程序来执行此操作(尽管无论如何我似乎都必须这样做)。
Anyone got any hints? 有人有提示吗? Here is the stacktrace The stacktrace is as follows:
这是stacktrace的堆栈跟踪如下:
play.exceptions.JavaExecutionException: Expecting a stackmap frame at branch target 36 in method controllers.SomeController.somemethod(Ljava/lang/String;)V at offset 14
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:237)
at play.server.ServletWrapper$ServletInvocation.execute(ServletWrapper.java:561)
at play.Invoker$Invocation.run(Invoker.java:278)
at play.server.ServletWrapper$ServletInvocation.run(ServletWrapper.java:552)
at play.Invoker.invokeInThread(Invoker.java:68)
at play.server.ServletWrapper.service(ServletWrapper.java:143)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.VerifyError: Expecting a stackmap frame at branch target 36 in method controllers.SomeController.somemethod(Ljava/lang/String;)V at offset 14
at controllers.SomeController.someOtherMethod(SomeController.java:83)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
at play.server.ServletWrapper$ServletInvocation.execute(ServletWrapper.java:561)
at play.Invoker$Invocation.run(Invoker.java:278)
at play.server.ServletWrapper$ServletInvocation.run(ServletWrapper.java:552)
at play.Invoker.invokeInThread(Invoker.java:68)
at play.server.ServletWrapper.service(ServletWrapper.java:143)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
... 1 more
Since Java 7, the byte code format requires so called stack map frames at each target of a jump instruction. 从Java 7开始,字节码格式在跳转指令的每个目标处都需要所谓的堆栈映射帧。 Before, the JVM's verifier applied type inference to assure the validity of the byte code.
之前,JVM的验证程序使用类型推断来确保字节码的有效性。 However, with Java 7, the verifier needs this information to be put in the class file, otherwise, you encounter this
VerifierError
. 但是,对于Java 7,验证者需要将此信息放入类文件中,否则,您将遇到此
VerifierError
。
The unfortunate answer is that the information is not there unless you put it there. 不幸的答案是信息不存在,除非您将其放在那里。 It is so to say not a bug of Javassist which is able to add these stack map frames, it is a problem of the Play framework not instructing Javassist to do so.
可以说不是Javassist的bug能够添加这些堆栈映射框架,而是Play框架没有指示Javassist这样做的问题。 Play is using Javassist's low level API which does not add these frames manually.
Play正在使用Javassist的低级API,该API不会手动添加这些帧。 It is absolutely possible to do this with Javassist as discussed for example for PowerMock .
如PowerMock所讨论的,使用Javassist完全可以做到这一点。
You might need to upgrade to version 2 of the Play framework. 您可能需要升级到Play框架的版本2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.