Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3 WARNING: A Java agent has been loaded dynamically (C:\Users\Lenovo\.m2\repository\net\bytebuddy\byte-buddy-agent\1.17.6\byte-buddy-agent-1.17.6.jar) WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information WARNING: Dynamic loading of agents will be disallowed by default in a future release OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
时间: 2025-08-07 22:07:05 浏览: 15
<think>我们正在解决一个关于Mockito的警告问题:在未来的JDK版本中,通过self-attaching启用inline-mock-maker的方式将被移除。我们需要正确地将Mockito添加为Java代理(Java agent)来避免这个警告,并确保未来的兼容性。
警告信息:`self-attaching to enable inline-mock-maker will be removed in future JDK versions.`
这个警告的原因是Mockito在尝试通过自我附加(self-attaching)来启用内联模拟生成器(inline mock maker)。在JDK的将来版本中,这种自我附加的方式可能会被禁止,因此我们需要以正确的方式添加Mockito作为Java代理。
解决方案:
根据Mockito的官方文档,正确的方式是在启动JVM时通过`-javaagent`参数添加`mockito-agent`的jar包。这样Mockito就可以在需要的时候使用内联模拟生成器,而无需自我附加。
步骤:
1. **添加依赖**:首先,确保你的项目中包含了`mockito-agent`的依赖。在Maven项目中,添加如下依赖(注意:使用最新版本,这里以5.7.0为例,请根据实际情况选择):
```xml
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-agent</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
```
2. **配置Java代理**:在运行测试时,需要将Mockito作为Java代理启动。具体配置方式取决于你使用的测试运行器或构建工具。
- **使用Maven Surefire插件(Maven项目)**:
在pom.xml中配置Surefire插件,添加`-javaagent`参数:
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version> <!-- 使用最新版本 -->
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/mockito/mockito-agent/5.7.0/mockito-agent-5.7.0.jar"
</argLine>
</configuration>
</plugin>
</plugins>
</build>
```
注意:上面的路径需要根据你的实际仓库路径和版本进行调整。一个更通用的方式是使用Maven属性来定位jar包:
```xml
<properties>
<mockito.version>5.7.0</mockito.version>
</properties>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/mockito/mockito-agent/${mockito.version}/mockito-agent-${mockito.version}.jar"
</argLine>
</configuration>
</plugin>
</plugins>
</build>
```
但是,上述方式依赖于本地仓库路径,可能在不同环境中会有问题。另一种方法是使用`org.apache.maven.plugins.surefire`的`classpathDependencyExcludes`和`classpathDependencyScopeExclude`,但这样并不直接。因此,Mockito官方推荐使用`mockito-extensions`机制,但在这种情况下,我们确实需要配置代理。
实际上,Mockito从5.0.0版本开始,提供了更简单的方式:你只需要在测试资源目录(通常是`src/test/resources`)下创建一个文件`/mockito-extensions/org.mockito.plugins.MockMaker`,其内容为`mock-maker-inline`。但这种方式在JDK的未来版本中可能还是会有警告,因为Mockito仍然会尝试自我附加。因此,正确的方式是使用Java代理。
- **使用Gradle**:在Gradle中,可以通过配置测试任务来添加代理:
```groovy
test {
jvmArgs "-javaagent:${classpath.find { it.name.contains('mockito-agent') }.absolutePath}"
}
```
这个配置会从测试类路径中找到`mockito-agent`的jar包,并将其作为代理添加。
3. **验证**:运行测试,警告应该消失。
4. **注意事项**:
- 确保你使用的Mockito版本是5.0.0以上,因为旧版本可能不支持这种方式。
- 如果你同时使用其他Java代理(如JaCoCo),需要确保多个代理都正确添加。在Surefire中,可以这样写:
```xml
<argLine>
-javaagent:path/to/mockito-agent.jar -javaagent:path/to/jacocoagent.jar
</argLine>
```
5. **替代方案(不推荐)**:如果你不想使用Java代理,也可以考虑使用Mockito的内联模拟生成器的替代方案,比如使用`@Mock`注解和`MockitoAnnotations.openMocks(this)`或`MockitoRule`/`MockitoExtension`来创建模拟对象,避免使用内联模拟生成器(例如`Mockito.mockStatic`等需要内联模拟生成器的功能)。但这样会限制Mockito的一些功能。
总结:通过添加Java代理的方式,可以避免自我附加,从而消除警告并保证未来兼容性。
参考资料:
[Mockito官方文档](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#39) 提到内联模拟生成器需要Java代理,并说明了如何配置。
生成的相关问题:
1. 如何在IntelliJ IDEA中配置运行测试时的Java代理参数?
2. Mockito的内联模拟生成器(inline mock maker)有什么作用?
3. 除了使用Java代理,还有其他方法解决Mockito的警告吗?
4. 如何同时配置多个Java代理(如Mockito和JaCoCo)?</think>### 解决 Mockito 警告 "self-attaching to enable inline-mock-maker will be removed in future JDK versions"
#### 问题原因
该警告表明 Mockito 试图通过自我附加(self-attaching)的方式启用 `inline-mock-maker`,但这种方式在未来的 JDK 版本中将不再支持。核心问题在于 Mockito 需要 Java Agent 权限来修改字节码以实现高级模拟功能(如 `mockStatic()` 或 `mockConstruction()`),但未正确配置 Java Agent[^1]。
---
### 解决方案(两种方式)
#### ✅ 方案 1:通过 JVM 参数添加 Java Agent(推荐)
在测试运行时显式添加 Mockito 作为 Java Agent:
1. **获取 mockito-agent 路径**
- Maven 项目:通过 Maven 依赖解析路径
```xml
<!-- pom.xml 添加依赖 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-agent</artifactId>
<version>5.7.0</version> <!-- 使用最新版本 -->
<scope>test</scope>
</dependency>
```
2. **配置测试运行参数**
- **Maven Surefire 配置**:
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/mockito/mockito-agent/5.7.0/mockito-agent-5.7.0.jar
</argLine>
</configuration>
</plugin>
</plugins>
</build>
```
- **Gradle 配置**:
```groovy
test {
jvmArgs = [
"-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('mockito-agent') }}"
]
}
```
- **IntelliJ IDEA 配置**:
```
Run → Edit Configurations → Templates → JUnit
在 VM options 添加:
-javaagent:/path/to/mockito-agent-5.7.0.jar
```
#### ✅ 方案 2:完全禁用 inline-mock-maker(简易方案)
如果不需要模拟静态方法/构造函数,可在 `src/test/resources/mockito-extensions` 目录创建文件 `org.mockito.plugins.MockMaker`,内容为:
```
mock-maker-inline-disabled
```
---
### 验证是否生效
1. 运行测试时检查日志:
```
[INFO] Mockito initialization on JVM started with: -javaagent:mockito-agent.jar
```
2. 警告应消失,且 `mockStatic()` 等功能仍正常工作
---
### 技术原理
| 机制 | 工作原理 | 兼容性 |
|------|----------|--------|
| **Java Agent** | 通过 JVM 的 `Instrumentation API` 修改字节码 | JDK 9+ 兼容 |
| **Self-attaching** | 运行时动态附加到自身 JVM | JDK 17+ 已弃用 |
| **inline-mock-maker** | 修改 final 类/方法的字节码实现模拟 | 需要 Agent 权限 |
> **关键点**:从 Mockito 4.8+ 开始,必须通过显式 Agent 配置启用内联模拟[^1]。JDK 17 的强封装性(JEP 403)限制了运行时自我附加。
阅读全文
相关推荐















