【发布时间】:2021-11-10 18:43:43
【问题描述】:
当我尝试测试使用 ByteBuddy 编写的 Java 代理时,我遇到了一些奇怪的行为
代理拦截带注释的方法/类并分析它们,没什么复杂的
class ByteInstrumentationConfigurer implements BootstrapConfigurer {
@Override
void init(...) {
def instrumentation = ByteBuddyAgent.install()
new AgentBuilder.Default()
.type(isAnnotatedWith(TimeProfiling.class))
.transform((builder, typeDescription, classLoader, module) ->
builder.method(not(isAnnotatedWith(Generated))) //ignore groovy generated methods (getMetaClass, etc.)
.intercept(MethodDelegation.to(TimeProfilingInterceptor.class)))
.with(stdoutToLoggerWriter.withTransformationsOnly())
.installOn(instrumentation)
我已经进行了一些单元测试,以验证是否调用了拦截器方法
class TimeProfilingInterceptorTest {
static MockedStatic<TimeProfilingInterceptor> timeProfilingInterceptorMockedStatic
static {
//agent installation happens here
new ByteInstrumentationConfigurer().init([:], [:])
timeProfilingInterceptorMockedStatic = mockStatic(TimeProfilingInterceptor, CALLS_REAL_METHODS)
}
@Test
void profilingEnabledClassLevelTest() {
//some mocking for my classes here
testCallingComponent.callClassLevelComponentMethod()
timeProfilingInterceptorMockedStatic.verify(()->
TimeProfilingInterceptor.measureAndLogExecutionTime(any(),any(),any()),times(2))
}
现在,当我使用从 IDEA 开始这个测试时,我看到,我的 2 个类被转换了
[字节好友] 转换 com.kmslh.manager.profiling.components.MethodLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, 线程[main,5,main], 加载=假]
[字节好友] 转换 com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, 线程[main,5,main], 加载=假]
但是,如果我使用 gradle test\build 任务运行此测试 - 没有转换任何类。如果我输出完整信息 - 我看到在这种情况下类加载器是 org.codehaus.groovy.runtime.callsite.CallSiteClassLoader。
[字节好友] 发现 com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false] [Byte Buddy] IGNORE com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false] [Byte Buddy] 完成 com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false]
不确定这是否是一个问题,但我没有想法。我还尝试将测试重写为 Java - 没有结果。
有什么建议可以试试?
UPD 1
据我所见 - 当测试从 gradle 开始时 - 没有创建 auxiliary 类
UPD 2
我使用-verbose:class 运行 gradle 任务,看到我的类在开始检测之前加载
[Loaded com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent from file:/C:/Users/.../build/classes/groovy/main/]
当 IDEA 运行测试时(将其打包到 jar 中并运行 jar)- 在检测之后加载类
UPD 3
[已加载 com....ClassLevelTimeProfilingComponent 来自 文件:/C:/Users/../build/classes/groovy/test/]
[已加载 com....ClassLevelTimeProfilingComponent 来自 VM_RedefineClasses]
[字节好友] TRANSFORM com....ClassLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@73d16e93,空,线程[测试 worker,5,main],loaded=true]
[已加载 com....ClassLevelTimeProfilingComponent$exposedMethod 来自 文件:/C:/Users/79270/IdeaProjects/kms-trunk/KMS-Manager/build/classes/groovy/test/]
【问题讨论】:
标签: java gradle groovy junit5 byte-buddy