У меня есть регрессионный тест, в котором я пытаюсь подсчитать количество экземпляров массивов. В частности, мне интересно посчитать, сколько раз вызывается new int[..]
. Я собрал следующие инструменты, основанные на рекомендациях ByteBuddy, которые, как мне кажется, должны улавливать все конструкторы, но это не работает для массивов (любого типа):
public class InstanceCounter {
public static void load() {
ClassInjector.UsingUnsafe.ofBootLoader().injectRaw(Collections.singletonMap("foo.bar.BootstrapState", readBytes(InstanceCounter.class.getClassLoader().getResource("foo/bar/BootstrapState.class"))));
new AgentBuilder.Default()
.ignore(none())
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE)
.type(any())
.transform(new Transformer() {
@Override
public Builder<?> transform(final Builder<?> builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) {
return builder.visit(Advice.to(InstanceCounter.class).on(any()));
}})
.installOn(ByteBuddyAgent.install());
}
@Advice.OnMethodEnter
public static void enter(final @Advice.Origin Class<?> origin) {
if (!BootstrapState.trace || BootstrapState.lock)
return;
BootstrapState.lock = true;
System.out.println(">>> " + origin);
BootstrapState.lock = false;
}
}
public class InstanceCounterTest {
@Test
public void test() {
InstanceCounter.load();
System.out.println("Creating array...");
BootstrapState.trace = true;
final Object[] y = new Object[3];
BootstrapState.trace = false;
System.out.println("Printing array: " + y);
}
}
Когда я запустите этот тест, я получу следующие результаты:
Creating array...
Printing array: [Ljava.lang.Object;@7f5eae0f
Если я изменю final Object[] y = new Object[3]
на new Object()
, то результат будет:
Creating array...
>>> class java.lang.Object
Printing array: [Ljava.lang.Object;@68562ad5
Я дал совет инструментарий как можно более открытый (по крайней мере, настолько открытый, насколько я думаю, я могу его сделать), но это все еще не инструментальное построение объектов массива.
Возможно ли даже инструментальное построение объектов массива?
Обновление 2020-07-28
В соответствии с контекстом исходного вопроса, предоставленные ответы express, что ByteBuddy не имеет прямой поддержки для автоматизации c аппаратура new int[]
. Тем не менее, для тех, кто заинтересован в альтернативном решении, я смог достичь такого рода инструментов с помощью Byteman .