我想使用javassist(版本3.19-GA)生成启动线程的类的静态初始化程序的字节码。出于某种原因,我无法理解javassist期望&#34 ;;"即使我相信我提供的代码在语法上是正确的。有人看到的比我多吗?这是代码。有什么问题?
ClassPool pool = ClassPool.getDefault();
final CtClass clazz = pool.get(somename);
clazz.makeClassInitializer().insertAfter(
"try{Runnable r=new Runnable () {public void run () { System.out.println (\"hello!!!!\"); }}; " +
"new Thread(r).start(); } catch(Exception e){}");
我收到以下异常:
javassist.CannotCompileException: [source error] ; is missing
at javassist.CtBehavior.insertAfter(CtBehavior.java:877)
at javassist.CtBehavior.insertAfter(CtBehavior.java:792)
at my.code(myclass.java:111)
感谢任何提示。
答案 0 :(得分:1)
很可能javassist编译器不支持匿名内部类,如new Runnable () {...}
您必须创建新类,从Runnable
继承它,实现方法run
并在构造函数中创建此类的对象。
package hello;
import javassist.*;
class Test{
}
class Main {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
final CtClass clazz = pool.get(Test.class.getCanonicalName());
CtClass runnable = pool.makeClass("my.custom.RunnableImpl");
runnable.addInterface(pool.get("java.lang.Runnable"));
CtMethod method = CtNewMethod.make("public void run() { System.out.println(\"hello!!!!\"); }", runnable);
runnable.addMethod(method);
// load class
runnable.toClass();
clazz.setName("newTest");
CtConstructor ctConstructor = clazz.makeClassInitializer();
ctConstructor.insertAfter("try{ new Thread( new my.custom.RunnableImpl() ).start(); } catch(Exception e){}");
Class aClass = clazz.toClass();
// call initializer
Class.forName(aClass.getCanonicalName());
Thread.sleep(1000);
}
}
答案 1 :(得分:0)
来自void insertAfter(String src)
的正式文件:
<强>参数强>:
src - 表示插入的字节码的源代码。它必须是一个 单一陈述或阻止。
在src
String
参数中,您不提供单个语句或块。
一个块是"{}"
。
尝试使用全局封闭insertBefore(String src)
的{{1}}方法:
"{}"