javassist一个很奇怪的问题

采用javassist来将一个类中的field改变类型。待改变的类代码如下:

[code="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);
}

}[/code]

进行改变操作的类如下:
[code="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);



}

}
[/code]

class文件生成后,我用反编译工具查看,Javassist已经变为如下:

[code="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);
}
}[/code]

但当我执行TestMain.java文件中的test.doit()方法时,还是报异常了。
[code="java"]Exception in thread "main" java.lang.NoSuchFieldError: stpService
at JassistTest.doit(JassistTest.java:13)
at TestMain.main(TestMain.java:33)
[/code]

实在搞不懂,请教大家

1个回答

感觉跟classloader有关,
试试这样,分开两次执行。第一次生成新的class,第二次把在path里直接使用新的class文件

iteye_2355
iteye_2355 我自己2了。class文件在生成时候已经记录field和method的相关信息了。如果改了field的类型,那么对应函数确实已经不能用了。
大约 7 年之前 回复
suziwen
suziwen 这个我现在也不太确定,现在对classloader的具体顺序也是忘记差不多了。只是感觉你new的话,可能这个class定义 已经加载到内存里了,所以还是旧的class
大约 7 年之前 回复
iteye_2355
iteye_2355 我用javassist在writefile的时候,是覆盖回classpath下的class文件,然后new的时候,classloader才去读取的吧?那时候已经重写完class文件了应该。
大约 7 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问