You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用使用Mockito的mock-maker-inline扩展初始化失败问题

问题描述

我有一个Spring Boot Web应用,可在特殊模式下运行,该模式下会使用Mockito对部分对象执行spy操作,其中部分对象为final类(protobuf消息类)。我知晓该方案可能并非最佳实践,目前仅作为实验性质进行验证。当我启用mock-maker-inline扩展以支持对final类执行spy操作时,遇到了疑似与Byte Buddy、原生库加载相关的问题;不启用该扩展(也不对final类执行spy操作)时,应用一切运行正常。截断后的异常栈信息如下:

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
…
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@60cc2b75
…
Caused by: java.lang.reflect.InvocationTargetException
…
Caused by: org.mockito.exceptions.base.MockitoInitializationException:
Could not initialize inline Byte Buddy mock maker.

It appears as if your JDK does not supply a working agent attachment mechanism.
Java               : 1.8
JVM vendor name    : AdoptOpenJDK
JVM vendor version : 25.265-b01
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 1.8.0_265-b01
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 10.15.7
…
Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@633c165e
…
Caused by: java.lang.reflect.InvocationTargetException
…
Caused by: java.lang.UnsatisfiedLinkError: Native Library /Users/…/.sdkman/candidates/java/8.0.265.hs-adpt/jre/lib/libattach.dylib already loaded in another classloader
问题根因

该报错的核心原因是JDK 8的libattach.dylib原生库为全局单例设计,仅允许被同一个类加载器加载一次。当前运行环境中已有其他组件(比如诊断工具、debug代理、其他需要attach能力的框架)提前通过另一个类加载器加载了该原生库,Mockito的inline mock maker初始化时尝试动态attach、再次加载该库就会触发冲突报错。

可行解决方案
  • 方案1:启动时预加载Byte Buddy Agent,跳过运行时动态attach逻辑
    启动应用时在JVM参数中添加-javaagent:/path/to/byte-buddy-agent-<对应版本号>.jar,让Byte Buddy Agent在JVM启动阶段就完成初始化,不需要在运行时动态加载attach库,从根源避免重复加载冲突。Byte Buddy Agent的版本要和当前Mockito依赖的Byte Buddy版本完全一致,避免版本兼容问题。
  • 方案2:统一Byte Buddy相关类的类加载器
    如果应用使用了自定义类加载器、或者Spring Boot FatJar的分层类加载逻辑,把Byte Buddy、Mockito相关依赖调整为应用全局统一的类加载器加载,保证全应用生命周期内只会初始化一次Byte Buddy Agent,仅触发一次libattach.dylib的加载。
  • 方案3:升级JDK版本
    JDK 9及以上版本优化了原生库的类加载器隔离规则,该重复加载冲突问题在JDK 11及以上的LTS版本中已经被修复,如果业务允许升级JDK版本,这是长期稳定的解决方式。
  • 方案4(本地临时验证用):如果仅在本地做实验验证,可以先关闭本地正在运行的、会用到JVM attach能力的工具(比如Arthas、Debug代理、JProfiler等),再启动应用,避免外部工具提前加载attach库导致冲突。

补充说明:当前用spy操作Protobuf生成的final类的场景,需要注意Protobuf生成的类默认是不可变的,spy时不要尝试修改类内部的私有字段,仅做方法返回值Mock即可,避免出现不可预期的序列化/反序列化异常。

内容的提问来源于stack exchange,提问作者marcin_koss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 02:12:00