解决JVM“函数调用的不兼容对象参数”错误(javassist instrumentation)

时间:2013-03-30 02:16:12

标签: java jvm javassist

我正在使用JVM(1.6.0b33)在我的一个类上抛出java.lang.VerifyError(函数调用的不兼容对象参数)。使用javassist(使用CtMethod.make())对类进行了检测(只有这一个方法)

有没有办法让我找到哪个方法调用会触发错误?我浏览了javap -c -s -l的输出,但我没有看到任何调用指令有任何问题。

如果有人知道如何让JVM提供更多详细信息(代码地址会很好)关于检测到这个错误的位置,例如,就足够了,所以我知道应该关注哪里。我可以发布javap的输出,如果有人想以这种方式对它进行破解......

1 个答案:

答案 0 :(得分:3)

在检查JVM源代码后计算出来。

错误(函数调用的不兼容对象参数)意味着执行调用的对象与预期(通过方法签名)类型不匹配(我假设它有事情要做)使用对象参数,但在这种情况下会出现稍微不同的错误。)

显然,当您将对象分配给另一个类的对象时,javassist不会插入正确的指令(或者它可能会使语句失败)。

Javassist将以下代码视为有效:

Object x ...;
String s = x; // javac requires cast here, javassist doesn't
s.isEmpty();

通常编译成:

1 aload_1 // push x on stack
2 checkcast java/lang/String // check we can fit x into s
3 astore 2 // s = x;
4 aload 2 // 'this' for isEmpty()
5 invokevirtual String.isEmpty() // stack top used as 'this'

javassist(至少是我的版本)只是不添加 checkcast 指令,并且VM无法保证当时 invokevirtual 被称为堆栈top包含String,这是必需的,因为 invokvirtual 正在调用String类中的方法。

补救措施是:

  • 在作业中使用显式转换
  • 修复javassist
  • 使用显式类型的局部变量