采用javassist来将一个类中的field改变类型。待改变的类代码如下:
Java代码 收藏代码
public class JassistTest {
@Autowired
private StpService stpService;
public void doit(Long userid){
PeakSeasonMainResponse res = stpService.getPeakOverView(userid);
System.out.println(stpService.getClass().getName());
System.out.println("hello" + res);
}
}
进行改变操作的类如下: Java代码 收藏代码
public class TestMain {
public TestMain(){
}
public static void main(String[] args) throws Exception{
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("JassistTest");
CtField f = cc.getDeclaredField("stpService");
cc.removeField(f);
cc.addField(CtField.make("private Proxy stpService;", cc));
cc.writeFile("D:\\DevProgram\\eclipse-jee-kepler-R-win32\\workspace\\stable\\fc-deimos\\target\\test-classes");
JassistTest test = new JassistTest();
test.doit(7060L);
}
}
class文件生成后,我用反编译工具查看,Javassist已经变为如下:
Java代码 收藏代码
public class JassistTest
{
private Proxy stpService;
public void doit(Long userid)
{
PeakSeasonMainResponse res = this.stpService.getPeakOverView(userid);
System.out.println(this.stpService.getClass().getName());
System.out.println("hello" + res);
}
}
但当我执行TestMain.java文件中的test.doit()方法时,还是报异常了。 Java代码 收藏代码
Exception in thread "main" java.lang.NoSuchFieldError: stpService
at JassistTest.doit(JassistTest.java:13)
at TestMain.main(TestMain.java:33)
感觉跟classloader有关, 试试这样,分开两次执行。第一次生成新的class,第二次把在path里直接使用新的class文件 我用javassist在writefile的时候,是覆盖回classpath下的class文件,然后new的时候,classloader才去读取的吧?那时候已经重写完class文件了应该。
这个我现在也不太确定,现在对classloader的具体顺序也是忘记差不多了。只是感觉你new的话,可能这个class定义 已经加载到内存里了,所以还是旧的class 我自己2了。class文件在生成时候已经记录field和method的相关信息了。如果改了field的类型,那么对应函数确实已经不能用了。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。