三藏 2013-11-05 02:01 采纳率: 0%
浏览 1928

关于javassist重复加载的问题

最近需要使用javassist动态改变类里的方法,问题是javassist使用过一次以后,第二次使用就会冻结,可是在第二次就算用了解冻,调用toclass以后还是会报异常,主要是为了得到frmAttributesI的实体,怎样已经冻结的class解冻之后还可以继续编辑修改并调用呢?
String body = null;
CtClass cc = null;
IFrmAttributes frmAttributesI = null;
//从数据查找判断是否是二次加载
String isCondUpdate = "Y";
if(isClassInit == false){
//第一次调用
// 获取所有条件信息(执行脚本)

            ClassPool pool = ClassPool.getDefault();

            //导入相关jar包
            pool.importPackage("java.util.Hashtable");
            pool.importPackage("java.util.List");
            pool.importPackage("java.util.Date");
            pool.importPackage("java.text.SimpleDateFormat");

            // 在外部变量执行类中,动态加载外部变量执行算法
            cc = pool.get("com.process.FrmAttributes");

            CtMethod cm = cc.getDeclaredMethod("process");
            //cc.defrost();
            System.out.println("测试1=================="+body.toString());
            cm.setBody("{" + body.toString() + "}");
            Class c = cc.toClass();

            frmAttributesI = (FrmAttributes) c.newInstance();
            this.isClassInit = true;
        }else{
            if(isCondUpdate == "Y"){
                frmAttributesI = null;

                ClassPool pool2 = ClassPool.getDefault();
                cc = pool2.get("com.process.FrmAttributes");

                if(cc.isFrozen()){
                    cc.defrost();
                }

                //删除方法,增加方法,试试二次加载
                //第二次调用
                CtMethod cm2 = cc.getDeclaredMethod("process");
                System.out.println("测试2============================"+body.toString());
                cm2.setBody("{" + body.toString() + "}");

                cc.writeFile();

                Class c = cc.toClass();
                frmAttributesI = (FrmAttributes) c.newInstance();
            }
        }
  • 写回答

1条回答

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-12-09 21:53
    关注

    所有内容均由人工智能模型输出,其内容的准确性和完整性无法保证,不代表我的态度或观点。
    (讯飞星火专栏,V3.0版本,2023.10.24)


    该回答引用讯飞星火认知大模型,仅提供参考,不保证完全正确
    在第二次调用时,如果类已经被冻结,需要先解冻再进行修改。你已经使用了cc.defrost()方法来解冻类,但是在调用cm2.setBody("{" + body.toString() + "}")之前,你需要确保类已经被重新加载。你可以尝试在设置新的方法体之后,使用cc.writeFile()方法将修改后的类写入文件,然后再次调用cc.toClass()方法来重新加载类。以下是修改后的代码:

    String body = null;
    CtClass cc = null;
    IFrmAttributes frmAttributesI = null;
    //从数据查找判断是否是二次加载
    String isCondUpdate = "Y";
    if(isClassInit == false){
        //第一次调用
        // 获取所有条件信息(执行脚本)
    
        ClassPool pool = ClassPool.getDefault();
    
        //导入相关jar包
        pool.importPackage("java.util.Hashtable");
        pool.importPackage("java.util.List");
        pool.importPackage("java.util.Date");
        pool.importPackage("java.text.SimpleDateFormat");
    
        // 在外部变量执行类中,动态加载外部变量执行算法
        cc = pool.get("com.process.FrmAttributes");
    
        CtMethod cm = cc.getDeclaredMethod("process");
        //cc.defrost();
        System.out.println("测试1=================="+body.toString());
        cm.setBody("{" + body.toString() + "}");
        cc.writeFile(); // 将修改后的类写入文件
        Class c = cc.toClass(); // 重新加载类
    
        frmAttributesI = (FrmAttributes) c.newInstance();
        this.isClassInit = true;
    }else{
        if(isCondUpdate == "Y"){
            frmAttributesI = null;
    
            ClassPool pool2 = ClassPool.getDefault();
            cc = pool2.get("com.process.FrmAttributes");
    
            if(cc.isFrozen()){
                cc.defrost();
            }
    
            //删除方法,增加方法,试试二次加载
            //第二次调用
            CtMethod cm2 = cc.getDeclaredMethod("process");
            System.out.println("测试2============================"+body.toString());
            cm2.setBody("{" + body.toString() + "}");
    
            cc.writeFile(); // 将修改后的类写入文件
    
            Class c = cc.toClass(); // 重新加载类
            frmAttributesI = (FrmAttributes) c.newInstance();
        }
    }
    

    这样修改后,你应该可以在第二次调用时正常修改类并创建实例了。

    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 MATLAB动图问题
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名