Javassist – CtMethod方法体中的数字操作引发java.lang.VerifyError错误。

huangapple go评论79阅读模式
英文:

Javassist - Numeric operations in CtMethod method body throws java.lang.VerifyError

问题

请参阅使用 javassist 创建类和方法的代码示例:

public Class generateClass(String className, String methodName)
                throws CannotCompileException, NotFoundException {
   ClassPool pool = ClassPool.getDefault();
   CtClass cc = pool.makeClass(className);

   ClassLoader classLoader = FormulaAPI.class.getClassLoader();
   pool.appendClassPath(new LoaderClassPath(classLoader));
   pool.importPackage("com.formula");

   String methodBody = "return ($w)($1.evaluate(\"L\") + 25.0);";

   CtClass apiClass = pool.get("com.formula.FormulaAPI");

   CtClass doubleWrapperClass = pool.get("java.lang.Double");

   CtMethod m = new CtMethod(doubleWrapperClass, methodName, new CtClass[]{apiClass}, cc);
   m.setBody(methodBody);
   cc.addMethod(m);

   return cc.toClass();
}

调用此方法后,我收到以下错误:

Exception in thread "main" java.lang.VerifyError: (class: Formulae, method: formula1 signature: (Lcom/formulabuilder/FormulaAPI;)Ljava/lang/Double;) Wrong return type in function

Javassist 是否不支持方法体中的数值操作?我试图在方法返回值之前调用一个方法并添加一个数字,如下所示:

String methodBody = "return ($w)($1.evaluate(\"L\") + 25.0);";

如何在方法体中实现 +、*、/、<、<= 等数值操作呢?

英文:

Please see below code of creating a class and method using javassist:

public Class generateClass(String className, String methodName)
            throws CannotCompileException, NotFoundException {
   ClassPool pool = ClassPool.getDefault();
   CtClass cc = pool.makeClass(className);

   ClassLoader classLoader = FormulaAPI.class.getClassLoader();
   pool.appendClassPath(new LoaderClassPath(classLoader));
   pool.importPackage(&quot;com.formula&quot;);

   String methodBody = &quot;return ($w)($1.evaluate(\&quot;L\&quot;) + 25.0);&quot;;

   CtClass apiClass = pool.get(&quot;com.formula.FormulaAPI&quot;);

   CtClass doubleWrapperClass = pool.get(&quot;java.lang.Double&quot;);

   CtMethod m = new CtMethod(doubleWrapperClass,methodName,new CtClass[]{apiClass},cc);
   m.setBody(methodBody);
   cc.addMethod(m);

   return cc.toClass();
}

After calling this method, I get the error:

Exception in thread "main" java.lang.VerifyError: (class: Formulae, method: formula1 signature: (Lcom/formulabuilder/FormulaAPI;)Ljava/lang/Double;) Wrong return type in function

Does Javassist not support numeric operations in method body? I am trying to call a method and add a number to it before it returns the value as below:

String methodBody = &quot;return ($w)($1.evaluate(\&quot;L\&quot;) + 25.0);&quot;;

How can I achieve numeric operations like +, *, /, <, <= etc. in method body?

答案1

得分: 1

问题很可能是javassist不支持自动装箱。因此,java.lang.Doubledouble不兼容。数值运算符仅适用于原始类型。

因此,如果您想保留这些签名,您需要自行对对象/原始类型进行装箱/拆箱。

类似这样的代码:

String methodBody = "return java.lang.Double.valueOf($1.evaluate(\"L\").doubleValue() + 25.0d);";

(如果evaluate()可能返回null,您可能需要添加null处理逻辑)

英文:

The problem is most likely that javassist doesnt support autoboxing. So java.lang.Double is not compatible with double. Numeric operators are only available for primitive types.

So if you want to keep the signatures, you need to box/unbox the objects/primitives yourself.

Something like

String methodBody = &quot;return java.lang.Double.valueOf($1.evaluate(\&quot;L\&quot;).doubleValue() + 25.0d);&quot;;

(you might want to add null handling if evaluate() can return null)

huangapple
  • 本文由 发表于 2020年3月16日 11:59:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/60700170.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定