Я пытаюсь перехватить конструкторы, аннотированные @Inject
. Это отлично работает в контексте небольшого модульного теста. Однако в контексте контейнера DI, такого как Spring, он терпит неудачу с ClassNotFoundException
.Перехват конструктора вызывает ClassNotFoundException
Мне удалось сузить основную причину. Вызов getDeclaredConstructors
на инструментальном классе вызовет это исключение. Интересно, что если мы сначала создадим экземпляр этого класса, проблема исчезнет.
Например:
public class InterceptConstructorTest {
@Test
public void testConstructorInterception() throws ClassNotFoundException {
ByteBuddyAgent.install();
new AgentBuilder.Default().type(nameStartsWith("test")).transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> builder, TypeDescription td) {
return builder.constructor(isAnnotatedWith(Inject.class))
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(ConstructorInterceptor.class)));
}
}).installOnByteBuddyAgent();
// If this line is uncommented, ClassNotFoundException won't be thrown
// MyClass myClass = new MyClass("a param");
// Manually load MyClass
Class<?> myClassDefinition = getClass().getClassLoader().loadClass("test.MyClass");
// Throws NoClassDefFoundError
for(Constructor<?> constructor : myClassDefinition.getDeclaredConstructors()) {
System.out.println(constructor);
}
}
}
Стек трассировки стека можно найти: http://pastebin.com/1zhx3fVX
class MyClass {
@Inject
public MyClass(String aParam) {
System.out.println("constructor called");
}
}
class ConstructorInterceptor {
public static void intercept() {
System.out.println("Intercepted");
}
}
Начиная с версии 0.7.7 Байт Бадди по умолчанию «InitiailizationStrategy» позаботится об этой проблеме. Новая версия в настоящее время синхронизирована с Центральным репозиторием Maven. –
После перехода на 0.7.7 мое приложение преждевременно выходит, прежде чем выполняется 'main'. Никаких исключений не было. Любая идея, как я могу помочь вам разобраться в этой проблеме? – user3408654
Этого не должно быть, даже если прибор не работает. Вы всегда можете добавить 'AgentBuilder.Listener', чтобы проверить, не выдает ли Byte Buddy ошибку. Может быть, ваш агент все еще использует старую версию Byte Buddy, вызывающую «NoClassDefFoundError»?Работает ли ваш блок с новой версией? Если это так, я предполагаю, что у вас конфликт версий. –