使用 Javassist 编辑 JFrame 时出现 IllegalAccessError Class
IllegalAccessError while using Javassist to edit JFrame Class
我正在使用 Javassist 在运行时编辑 JFrame
class,(添加一个新的构造函数)
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();setSize(,);}",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()
,但没有用。
您遇到的问题与包私有包的运行时定义有关。
Javassist 无法将 classes 注入负责 Swing 的 bootstrap class 加载器。相反,它会将更改后的 class 注入到系统 class 路径中。这个加载的 class 继承自包私有的 class,但是 "naturally" 由 bootstrap class 加载器加载。根据定义,这个包是一个不同的运行时包,因此不能通过其实现访问 class,导致非法访问错误。
我正在使用 Javassist 在运行时编辑 JFrame
class,(添加一个新的构造函数)
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();setSize(,);}",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()
,但没有用。
您遇到的问题与包私有包的运行时定义有关。
Javassist 无法将 classes 注入负责 Swing 的 bootstrap class 加载器。相反,它会将更改后的 class 注入到系统 class 路径中。这个加载的 class 继承自包私有的 class,但是 "naturally" 由 bootstrap class 加载器加载。根据定义,这个包是一个不同的运行时包,因此不能通过其实现访问 class,导致非法访问错误。