bytebuddy с контейнером osgi

Попытка написать простой java-агент на основе образца на домашней странице bytebuddy. У меня работает агент, но когда я запускаю его со средой выполнения OSGI, он выдает java.lang.NoClassDefFoundError.

Любые указатели?

java.lang.ClassNotFoundException: com.foo.javaagent.TimingInterceptor cannot be found by ..

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;


    public class TimerAgent {
        public static void premain(String arguments,
                                   Instrumentation instrumentation) {
            new AgentBuilder.Default()
                    .type(ElementMatchers.nameEndsWith("World"))
                    .transform((builder, type, classLoader, module) ->
                            builder.method(ElementMatchers.any())
                                    .intercept(MethodDelegation.to(TimingInterceptor.class))
                    ).installOn(instrumentation);
        }
    }

import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;


public class TimingInterceptor {
    @RuntimeType
    public static Object intercept(@Origin Method method,
                                   @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        try {
            return callable.call();
        } finally {
            System.out.println(method + " took " + (System.currentTimeMillis() - start));
        }
    }
}

person basu76    schedule 19.04.2017    source источник


Ответы (1)


На класс TimingInterceptor ссылаются ваши инструментальные классы, поэтому он должен быть видимым. OSGi изолирует классы по их загрузчикам классов и не устанавливает системный загрузчик классов в качестве родителя, в который загружается агент. Чтобы обойти это, вам нужно внедрить свои классы в загрузчик классов начальной загрузки, где они будут видны всем. Для этого изолируйте свою логику перехвата в отдельном jar-файле и прикрепите этот jar-файл к пути поиска загрузчика классов начальной загрузки через экземпляр Instrumentation, который вы используете для установки агента. Это необходимо сделать перед установкой агента.

person Rafael Winterhalter    schedule 19.04.2017
comment
Рафаэль - Большое спасибо за быстрый ответ. Вы создали замечательную библиотеку. Я смог заставить его работать. Есть ли примеры того, как изменить входные параметры метода, перехватчики HTTP с помощью байтового приятеля? - person basu76; 19.04.2017