IllegalAccessError при использовании Javassist для редактирования класса JFrame

Я использую 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,

Исключение в потоке «основной» javassist.CannotCompileException: от java.lang.IllegalAccessError: класс javax.swing.JFrame не может получить доступ к своему суперинтерфейсу javax.swing.TransferHandler$HasGetTransferHandler в javassist.ClassPool.toClass(ClassPool.java:1120) в javassist. ClassPool.toClass(ClassPool.java:1063) в javassist.ClassPool.toClass(ClassPool.java:1021) в javassist.CtClass.toClass(CtClass.java:1259) в io.github.potatophil.PSStart.compile(PSStart.java :46) в io.github.potatophil.PSStart.main(PSStart.java:24)
Причина: java.lang.IllegalAccessError: class javax.swing.JFrame не может получить доступ к своему суперинтерфейсу javax.swing.TransferHandler$HasGetTransferHandler at java.lang.ClassLoader.defineClass1 (собственный метод) в java.lang.ClassLoader.defineClass (ClassLoader.java: 760) в java.lang.ClassLoader.defineClass (ClassLoader.java: 642) в sun.reflect.NativeMethodAccessorImpl.invoke0 ( Натив e) в sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) в sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke(Method.java:497) на javassist.ClassPool.toClass2(ClassPool.java:1133) на javassist.ClassPool.toClass(ClassPool.java:1114) ... еще 10

Я пытался использовать pool.importPackage(), но безрезультатно.


person PotatoPhil    schedule 24.05.2015    source источник
comment
Почему вы хотите это сделать? Это как пытаться открыть маленькую дверь бульдозером, когда дверь уже открыта. После добавления этого конструктора не будет кода, вызывающего его, поэтому вам также придется сгенерировать этот код. Так почему бы не сгенерировать код, который просто использует существующий конструктор, за которым следует setSize(…) во фрейме? Как вы думаете, в чем преимущество этого конструктора, помимо того, что он делает ваш код неэффективным и в то же время неудобным в сопровождении?   -  person Holger    schedule 26.05.2015


Ответы (1)


Проблема, с которой вы столкнулись, связана с определением времени выполнения пакетов, приватных для пакетов.

Javassist не может внедрять классы в загрузчик классов начальной загрузки, отвечающий за Swing. Вместо этого он вставит измененный класс в системный путь к классу. Этот загруженный класс наследуется от закрытого для пакета класса, который, однако, загружается «естественным образом» загрузчиком классов начальной загрузки. По определению, этот пакет является другим пакетом среды выполнения и, следовательно, не может быть доступен его реализующему классу, что вызывает ошибку недопустимого доступа.

person Rafael Winterhalter    schedule 25.05.2015
comment
Я просто хочу сказать вам большое спасибо. Я столкнулся с этой проблемой локально, и объявление моего интерфейса, который я пытался сделать общедоступным, заставило его работать. - person Sam Sieber; 30.04.2020