首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BCEL能生成LocalVariableTable吗?

BCEL能生成LocalVariableTable吗?
EN

Stack Overflow用户
提问于 2013-10-24 04:23:59
回答 1查看 230关注 0票数 0

我遇到了一个无聊的错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack in method 
         net.madz.lifecycle.demo.standalone.ServiceOrder.allocateResources(JJJ)V at offset 27

我不太明白错误的意思。

我编写了一个类并生成了一个类,它们看起来非常相似:

写道:

代码语言:javascript
复制
    public void allocateResources(long arg0, long truckResourceId, long arg2) {
    /* L23 */
    0 new 2;
    3 dup;
    4 invokespecial 3;        /* net.madz.lifecycle.solutionOne.InterceptorController() */
    7 astore 7;               /* controller */
    /* L24 */
    9 new 4;
    12 dup;
    13 aload_0;               /* this */
    14 invokevirtual 5;       /* java.lang.Class getClass() */
    17 aload_0;               /* this */
    18 ldc 6;                 /* "allocateResources" */
    20 iconst_3;
    21 anewarray 7;           /* new java.lang.Class[] */
    24 dup;
    25 iconst_0;
    26 getstatic 8;           /* java.lang.Long.TYPE */
    29 aastore;
    30 dup;
    31 iconst_1;
    32 getstatic 8;           /* java.lang.Long.TYPE */
    35 aastore;
    36 dup;
    37 iconst_2;
    38 getstatic 8;           /* java.lang.Long.TYPE */
    41 aastore;
    42 invokespecial 9;       /* net.madz.lifecycle.solutionOne.InterceptContext(java.lang.Class summaryPlanId, java.lang.Object arg1, java.lang.String truckResourceId, java.lang.Class[] arg3) */
    45 astore 8;              /* context */
    /* L26 */
    47 aload 7;               /* controller */
    49 aload 8;               /* context */
    51 new 10;
    54 dup;
    55 aload_0;               /* this */
    56 lload_1;               /* summaryPlanId */
    57 lload_3;               /* truckResourceId */
    58 lload 5;               /* plangResourceId */
    60 invokespecial 11;      /* net.madz.lifecycle.solutionOne.ServiceOrder$1(net.madz.lifecycle.solutionOne.ServiceOrder summaryPlanId, long arg1, long truckResourceId, long arg3) */
    63 invokevirtual 12;      /* java.lang.Object exec(net.madz.lifecycle.solutionOne.InterceptContext arg0, java.util.concurrent.Callable truckResourceId) */
    66 pop;
    /* L34 */
    67 return;
}

产生:

代码语言:javascript
复制
    public void allocateResources(long arg0, long arg1, long arg2) {
    0 new 77;
    3 dup;
    4 invokespecial 78;       /* net.madz.lifecycle.solutionOne.InterceptorController() */
    7 astore 7;
    9 new 80;
    12 dup;
    13 ldc 7;
    15 aload_0;
    16 ldc 81;                /* "allocateResources" */
    18 iconst_3;
    19 anewarray 83;          /* new java.lang.Class[] */
    22 dup;
    23 iconst_0;
    24 getstatic 88;          /* java.lang.Long.TYPE */
    27 aastore;
    28 dup;
    29 iconst_1;
    30 getstatic 88;          /* java.lang.Long.TYPE */
    33 aastore;
    34 dup;
    35 iconst_2;
    36 getstatic 88;          /* java.lang.Long.TYPE */
    39 aastore;
    40 invokespecial 91;      /* net.madz.lifecycle.solutionOne.InterceptContext(java.lang.Class arg0, java.lang.Object arg1, java.lang.String arg2, java.lang.Class[] arg3) */
    43 astore 8;
    45 aload 7;
    47 aload 8;
    49 new 93;
    52 dup;
    53 aload_0;
    54 lload_1;
    55 lload_3;
    56 lload 5;
    58 invokespecial 96;      /* net.madz.lifecycle.demo.standalone.ServiceOrder$5(net.madz.lifecycle.demo.standalone.ServiceOrder arg0, long arg1, long arg2, long arg3) */
    61 invokevirtual 100;     /* java.lang.Object exec(net.madz.lifecycle.solutionOne.InterceptContext arg0, java.util.concurrent.Callable arg1) */
    64 pop;
    65 return;
}

因为它写着“方法net.madz.lifecycle.demo.standalone.ServiceOrder.allocateResources(JJJ)V中的操作数堆栈上的坏类型在偏移量27”

是“二十七号”造成了这一例外吗?在编写版本类时,我的意思是编写一个java文件并将其编译成类文件。我使用this.getClass()加载类引用,因此在编写版本中,“偏移”13和14是"aload_0;“和”Invokevirtu5“;但是在生成的版本中,我使用偏移量13处的”最不发达国家“直接引用类,因此这两个版本不能精确对齐。

通常情况下,如何诊断这些问题,以及如何在运行时监视操作数堆栈,BCEL能否将LocalVariableTable生成为类文件?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-24 05:25:23

最后,我尝试利用BCELifier从生成的和编写的类文件中生成Java代码,并发现它们之间的区别。

代码语言:javascript
复制
    public static void main(String[] args) throws Throwable {
    final JavaClass outerClass = Repository.lookupClass(ServiceOrder.class.getName());
    StringRepresentation s = new StringRepresentation(outerClass);
    System.out.println(s);
    BCELifier fier = new BCELifier(outerClass, System.out);
    fier.start();

    final JavaClass outer2Class = Repository.lookupClass(net.madz.lifecycle.solutionOne.ServiceOrder.class.getName());
    BCELifier fier2 = new BCELifier(outer2Class, System.out);
    fier2.start();

然后找出不同之处:

正确:

代码语言:javascript
复制
il.append(_factory.createFieldAccess("java.lang.Long", "TYPE", new ObjectType("java.lang.Class"), Constants.GETSTATIC));

错:

代码语言:javascript
复制
il.append(_factory.createFieldAccess("java.lang.Long", "TYPE", Type.LONG, Constants.GETSTATIC));

在我的代码中,实际上我使用的是:

代码语言:javascript
复制
ilist.append(ifact.createGetStatic(convertType2ClassName(type), "TYPE", Type.LONG));

显然,应该是:

代码语言:javascript
复制
ilist.append(ifact.createGetStatic(convertType2ClassName(type), "TYPE", new ObjectType("java.lang.Class")));

总之,我犯了两个错误:

  1. 我没有使用InstructionFactory.createFieldAccess方法,但是我选择了InstructionFactory.createGetStatic,虽然它们可以产生相同的结果,但是createFieldAccess有文档,而createGetStatic没有。
  2. 我应该使用新的ObjectType(Class.class.getName()),而不是Type.LONG,因为它应该是字段类型,应该与Class[]匹配。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19556894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档