2015-05-24 84 views
0

我使用了Javassist编辑在运行时JFrame类,(添加一个新的构造)IllegalAccessError同时使用了Javassist编辑JFrame类

ClassPool pool = ClassPool.getDefault(); 
pool.importPackage("javax.swing.TransferHandler$HasGetTransferHandler"); 
CtClass jFrameClass= pool.get("javax.swing.JFrame"); 
jFrameClass.addConstructor(CtNewConstructor.make(new CtClass[]{pool.get("java.lang.String"),CtClass.intType,CtClass.intType},new CtClass[0],"{this($1);setSize($2,$3);}",jframe)); 
jFrameClass.toClass(); 

不幸的是,这将引发一个IllegalAccessError

Exception in thread "main" javassist.CannotCompileException: by java.lang.IllegalAccessError: class javax.swing.JFrame cannot access its superinterface javax.swing.TransferHandler$HasGetTransferHandler at javassist.ClassPool.toClass(ClassPool.java:1120) at javassist.ClassPool.toClass(ClassPool.java:1063) at javassist.ClassPool.toClass(ClassPool.java:1021) at javassist.CtClass.toClass(CtClass.java:1259) at io.github.potatophil.PSStart.compile(PSStart.java:46) at io.github.potatophil.PSStart.main(PSStart.java:24)
Caused by: java.lang.IllegalAccessError: class javax.swing.JFrame cannot access its superinterface javax.swing.TransferHandler$HasGetTransferHandler at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:760) at java.lang.ClassLoader.defineClass(ClassLoader.java:642) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at javassist.ClassPool.toClass2(ClassPool.java:1133) at javassist.ClassPool.toClass(ClassPool.java:1114) ... 10 more

我曾尝试使用pool.importPackage(),无济于事。

+0

为什么你想这样做?这就像试图用推土机打开一扇小门,而门已经打开。添加构造函数后,将不会有代码调用它,因此您也必须生成该代码。那么为什么不生成简单地使用现有构造函数的代码,然后在框架上加上'setSize(...)'?你认为这个构造函数的优点是什么,除了让你的代码在低效率和不可维护的同时? – Holger

回答

1

您遇到的问题与包私有包的运行时定义有关。

Javassist无法将类注入到负责Swing的引导类加载器中。相反,它会将已更改的类注入到系统类路径中。这个加载的类继承自一个package-private类,然而这个类是由bootstrap类加载器“自然”加载的。根据定义,这个包是一个不同的运行时包,因此不能被其实现类访问,导致非法访问错误。