Подтвердить что ты не робот

Javassist загружает файл класса в предварительном основном методе (java instrumentation)

Я пытаюсь загрузить определенный класс с помощью javassist, я делаю это внутри основного метода в качестве следующего:

public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException 
{
   byte[] byteCode = classfileBuffer;

   if(className.toLowerCase().endsWith("class1"))
   {
       ClassPool classPool = ClassPool.getDefault();
       CtClass ctClass = classPool.get("com.class2");
   }
}

но неудобно, я получаю исключение NotFoundException....

com.class2 - это класс, который будет загружен загрузчиком классов после загрузки класса1, но я добавил, чтобы добавить новый метод для класса 1, который имеет тип возвращаемого типа com.class2

Я пробовал все решения внутри stackoverflow.com, но без каких-либо результатов.....

Наконец, как class1, так и class2 находятся в одном пакете и внутри одного JAR файла, class1 имеет член типа class2, но я понятия не имею, почему этот класс не может загрузить второй.

трассировка стека здесь:

Exception: javassist.NotFoundException: com.Class2
 javassist.NotFoundException: com.Class2
at javassist.ClassPool.get(ClassPool.java:439)
at javassist.ClassPool.getCtClass(ClassPool.java:504)
at com.stuff.MainAppletTransformer.transform(MainAppletTransformer.java:69)
at sun.instrument.TransformerManager.transform(Unknown Source)
at sun.instrument.InstrumentationImpl.transform(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.defineClassHelper(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.access$100(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
4b9b3361

Ответ 1

Ваш метод не имеет возвращаемого значения и поэтому не будет компилироваться. Тем не менее я могу сказать, что происходит не так: вы не настраиваете правильный путь поиска. Из вашей трассировки стека кажется, что вы используете апплет, который экранируется определенным ClassLoader. Этот классный загрузчик не отображается Javassist в вашей текущей версии.

Используя ClassPool.getDefault(), вы просматриваете информацию из пути к системному классу. Для вашего апплета вам, вероятно, понадобится добавить загрузчик классов, который передается методом transformatio в качестве аргумента.

Вы можете добавить загрузчик классов в путь поиска Javassist на

ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(new LoaderClassPath(classLoader));

После добавления этого пути ваш пример должен работать.