栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

java.lang.VerifyError:在分支目标处需要一个堆栈映射框架

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java.lang.VerifyError:在分支目标处需要一个堆栈映射框架

嗨,这与您的应用程序中的某些字节码有关。(有关Java
7兼容性更改的注释,请参见http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#incompatibilities,有关JSR
202,请看以下几行)

你可以

  • 用JDK 7重新编译所有源
  • 或者如果您无权访问源
    • java
      与参数一起使用
      -XX:-UseSplitVerifier
    • 或如果遇到使用开关的问题,则切换到Java 6

编辑 甚至答案已经有点老了。由于当前情况,我添加一些更详细的解释。

StackMapTable
Java引入了类文件中的属性,即使当时没有记录。

Foo.java

public class Foo {    public static boolean bar(String s) {        if (s.length() == 0) { return true;        }        return false;    }}$ java -versionjava version "1.6.0"Java(TM) SE Runtime Environment (build 1.6.0-b105)$ javac Foo.java$ javap -c -v FooCompiled from "Foo.java"public class Foo extends java.lang.Object  SourceFile: "Foo.java"  minor version: 0  major version: 50...public static boolean bar(java.lang.String);  Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   invokevirtual   #2; //Method java/lang/String.length:()I   4:   ifne    9   7:   iconst_1   8:   ireturn   9:   iconst_0   10:  ireturn  LineNumberTable:    line 3: 0   line 4: 7   line 6: 9  StackMapTable: number_of_entries = 1   frame_type = 9 }

类验证器不检查属性是否在类中。

以下创建

Foo.class
不带
StackMatTable
属性的文件。

FooDump.java

import org.objectweb.asm.*;import java.io.*;public class FooDump implements Oppres {    public static void main(String[] args) throws Exception {        FileOutputStream fos = new FileOutputStream("Foo.class");        fos.write(dump());        fos.close();    }    public static byte[] dump() throws Exception {        ClassWriter cw = new ClassWriter(0);        FieldVisitor fv;        cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Foo", null, "java/lang/Object", null);        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,  null);        mv.visitCode();        mv.visitVarInsn(ALOAD, 0);        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V",  false);        mv.visitInsn(RETURN);        mv.visitMaxs(1, 1);        mv.visitEnd();        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "bar",  "(Ljava/lang/String;)Z", null, null);        mv.visitCode();        mv.visitVarInsn(ALOAD, 0);        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I",  false);        Label l0 = new Label();        mv.visitJumpInsn(IFNE, l0);        mv.visitInsn(ICONST_1);        mv.visitInsn(IRETURN);        mv.visitLabel(l0);        // this line would generate the StackMapTable attribute        // mv.visitframe(Oppres.F_SAME, 0, null, 0, null);        mv.visitInsn(ICONST_0);        mv.visitInsn(IRETURN);        mv.visitMaxs(1, 1);        mv.visitEnd();        cw.visitEnd();        return cw.toByteArray();    }}

编译并运行它

$ javac -cp asm-5.2.jar:asm-util-5.2.jar:. FooDump.java$ java -cp asm-5.2.jar:asm-util-5.2.jar:. FooDump

检查

StackMapTable
属性是否不在文件中

$ javap -c -v Foopublic class Foo extends java.lang.Object  minor version: 0  major version: 50...public static boolean bar(java.lang.String);  Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   invokevirtual   #16; //Method java/lang/String.length:()I   4:   ifne    9   7:   iconst_1   8:   ireturn   9:   iconst_0   10:  ireturn}

FooDemo.java

public class FooDemo {    public static void main(String[] args) {        System.out.println("output: " + Foo.bar(""));    }}$ java -versionjava version "1.6.0"Java(TM) SE Runtime Environment (build 1.6.0-b105)$ javac FooDemo.java$java FooDemo output: true

使用Java 7时,类验证已更改。

对于版本为50(Java
6)的类文件,如果

StackMapTable
缺少或错误,则检查将进行故障转移(请参阅:jvms-4.10.1)。

使用

Foo
Java 6 的类版本运行检查。

$ java -versionjava version "1.7.0"Java(TM) SE Runtime Environment (build 1.7.0-b147)$ javap -c -v FooClassfile /home/suboptimal/playground/Foo.class  Last modified Jun 9, 2017; size 232 bytes  MD5 checksum 5a7ea4a5dd2f6d1bcfddb9ffd720f9c9public class Foo  minor version: 0  major version: 50 <-- class file Java 6...$ javac FooDemo.java$ java FooDemooutput: true

对于类文件版本51(Java 7)不再发生此故障转移。

要创建

Foo
Java 7 的类版本,请修改的代码
FooDump.java

// cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Foo", null, "java/lang/Object", null);cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "Foo", null, "java/lang/Object", null);

编译并运行它

$ javac -cp asm-5.2.jar:asm-util-5.2.jar:. FooDump.java$ java -cp asm-5.2.jar:asm-util-5.2.jar:. FooDump

检查它是否是类版本51

$ java -versionjava version "1.7.0"Java(TM) SE Runtime Environment (build 1.7.0-b147)$ javap -c -v FooClassfile /home/suboptimal/playground/Foo.class  Last modified Jun 9, 2017; size 232 bytes  MD5 checksum cfd57fb547ac98a1b2808549f5e9e8c1public class Foo  minor version: 0  major version: 51 <-- class file Java 7...$ javac FooDemo.java$ java FooDemoException in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 9 in method Foo.bar(Ljava/lang/String;)Z at offset 4

在Java
7中,

StackMapTable
可以使用选项UseSplitVerifier禁用对属性的类型检查,以退回到Java 6故障转移机制。

$ java -versionjava version "1.7.0"Java(TM) SE Runtime Environment (build 1.7.0-b147)$ java -XX:-UseSplitVerifier FooDemooutput: true

在Java 8中,

StackMapTable
必须对属性进行验证,并且
UseSplitVerifier
删除了该选项。

$ java -versionjava version "1.8.0"Java(TM) SE Runtime Environment (build 1.8.0-b132)$ javap -c -v FooClassfile /home/suboptimal/playground/Foo.class  Last modified Jun 9, 2017; size 232 bytes  MD5 checksum cfd57fb547ac98a1b2808549f5e9e8c1public class Foo  minor version: 0  major version: 51 <-- class file Java 7...$ javac FooDemo.java$ java FooDemoException in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 9$ java -XX:-UseSplitVerifier FooDemoJava HotSpot(TM) 64-Bit Server VM warning: ignoring option UseSplitVerifier; support was removed in 8.0Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 9

note注意 始终使用Java 6/7/8的初始版本是为了表明从一开始就存在这种行为。

您可能会发现一些建议,以使其在Java 8中运行。

$ java -noverify FooDemooutput: true$ java -Xverify:none FooDemooutput: true

注意 这将禁用字节码验证程序。请记住,切勿在生产系统中禁用字节码验证。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/466816.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号