Próbuję wyśmiać niektóre usługi w moim rozwijającym się środowisku. Kod serwisowy jest podobny do:jak zmienić wartość początkową pola za pomocą javassist
public class ApiFacadeImpl implements ApiFacade {
private OneService oneService = null;
public OneService getOneService(){
if(oneService==null) {//some initialization steps }
return oneService;
}
}
Wiem, że ta fabryka nie jest dobrze zakodowana i zaprojektowana. Nie mogę jednak zmodyfikować jego kodu. mój pomysł jest zmiana kodu bajtowego, więc mogę zdefiniować ją do czegoś podobnego:
public class ApiFacadeImpl implements ApiFacade {
private OneService oneService = new MyMockOneService();
....
}
Mój 1 jest: jest to możliwe przy użyciu javassist? I jak?
Ponieważ nie mogę znaleźć czegoś takiego ponownie zainicjować pole używając javassist za pomocą google, starałem się, usuwając je i odtworzyć go:
CtField oneServiceField = cc.getDeclaredField("oneService");
cc.removeField(oneServiceField);
CtField f = CtField.make(String.format("private %s %s=new %s();",
oneServiceField.getType().getName(), "oneService",
mockClass.getCanonicalName()), cc);
cc.addField(f);
cc.toClass();
potem mam wyjątek:
javassist.CannotCompileException: by java.lang.ClassFormatError: Invalid length 99 in LocalVariableTable in class file com/Test
at javassist.ClassPool.toClass(ClassPool.java:1051)
at javassist.ClassPool.toClass(ClassPool.java:994)
at javassist.ClassPool.toClass(ClassPool.java:952)
at javassist.CtClass.toClass(CtClass.java:1079)
Moje drugie pytanie brzmi: dlaczego ten wyjątek? Który krok nie pasuje do definicji klasy java? I kiedy usunąć pole robi javassist pomóc usunąć odniesienie pola w:
public OneService getOneService(){
if(oneService==null) {//some initialization steps }
return oneService;
}
Wielkie dzięki.
Co jest mockClass.getCanonicalName()? – longhua
Jaka jest twoja wersja javassist? – longhua