Создавая и впервые используя агента, я добился успеха. Я создал базовое приложение Java, чтобы использовать свой агент для отладки, и мой агент получил байт-код, как и ожидалось. Затем я приступил к добавлению javassist в свои библиотеки проектов и добавил некоторый соответствующий код для использования javassist. Я добавил javassist в свой артефакт (с помощью IntelliJ IDEA), чтобы он был упакован внутри банки с моим агентом. Я обнаружил, что после того, как мои изменения из javassist были внесены в мой код, вообще ничего не произошло. Затем я приступил к отладке с помощью операторов печати и обнаружил, что код действительно не работает. Зная это, я поместил вокруг кода оператор try catch и обнаружил, что в моем java-агенте происходит ошибка java.lang.NoClassDefFoundError, которая не транслировалась без оператора try catch. После этого я попытался создать свою собственную маленькую библиотечную банку с простым кодом, и она тоже не сработала в пакете с моим агентом. Пытаясь и пытаясь, я даже не могу заставить своего агента работать с библиотеками, размещенными рядом с jar-емкостью агента. Единственный вариант, который я могу придумать, чтобы заставить это работать, - это напрямую перетащить исходный код библиотеки в мой проект и использовать его.

Ниже приведены классы, которые я использую:

Главный класс агента:

package poisonedporkchop.agent;

import java.lang.instrument.Instrumentation;

public class Agent {
    public static void premain(String args, Instrumentation instrumentation){
        AgentClassTransformer transformer = new AgentClassTransformer();
        System.out.println("Injecting/editing jar...");
        instrumentation.addTransformer(transformer);
    }
}

Класс агента-трансформера:

package poisonedporkchop.agent;

import testpackage.TestClass;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

public class AgentClassTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytecode) throws IllegalClassFormatException {
        System.out.println("Class Received: " + className);
        if(className.equals("poisonedporkchop/testapp/Main"))
        {
            try {
                System.out.println("Main found!");
                System.out.println("Test if it it even getting here."); //Nothing after this works.
                TestClass test = new TestClass();
                System.out.println("T1");
                test.testMethod();
                System.out.println("T2");
                System.out.println(TestClass.testStatic);
                System.out.println("Test if it is getting to the end.");
            }
            catch (Throwable e)
            {
                e.printStackTrace();
            }
        }
        return bytecode;
    }
}

Манифест: (Для агента требуется настраиваемый манифест)

Manifest-Version: 1.0
Premain-Class: poisonedporkchop.agent.Agent

Версия IntelliJ IDEA: 2017.2.6 (сборка 172.4574.11)

Настройка проекта IntelliJ:

Настройка проекта

Настройка модуля

Я не понимаю, что мне делать. Обратите внимание, что я добавил библиотеку в банку в артефактах, как говорят многие решения, похожие на мою проблему. Любое руководство будет оценено.

0
PoisonedPorkchop 15 Фев 2018 в 07:53

1 ответ

Лучший ответ

Я обнаружил, что решение проблемы действительно заключается в извлечении исходного кода библиотеки в вашу банку.

Это можно сделать в IntelliJ IDEA следующим образом:

Щелкните правой кнопкой мыши свою библиотеку в Артефактах и ​​выберите эту опцию.

Это позволяет вам использовать свои библиотеки, не получая никаких ошибок NoClassDefFoundError.

0
PoisonedPorkchop 17 Фев 2018 в 03:27