JaCoCo(Java Code Coverage)是一个用于测量Java程序代码覆盖率的工具。它通过在运行时动态地对类文件进行插桩(instrumentation)来收集执行信息。
JaCoCo Agent的作用:
- 类文件增强:JaCoCo在类加载期间动态地增强类文件,实现执行覆盖数据的收集。
- Java代理:使用Java代理机制,在内存中预处理所有类文件,与应用框架无关。
JaCoCo Agent的集成:
- 如果使用JaCoCo的Ant任务或Maven插件,不需要直接关心代理及其选项,这些会被自动处理。
执行数据输出模式:
- 文件系统:JVM终止时,执行数据被写入本地文件。
- TCP套接字服务器server:外部工具可以通过套接字连接到JVM并检索执行数据。
- TCP套接字客户端client:JaCoCo代理在启动时连接给定的TCP端点,按需将执行数据写入套接字连接。
JaCoCo Agent的激活:
- Ant任务或Maven插件:如果使用JaCoCo的Ant任务或Maven插件,不需要直接处理代理及其选项。
- 代理激活:通过JVM选项激活JaCoCo代理,格式为
-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]
JaCoCo agent 是一个 Java Agent,它在 Java 程序运行时收集代码覆盖率信息。你可以通过在启动 Java 程序时添加 -javaagent 参数来使用 JaCoCo agent。
JaCoCo Agent接受的选项:
- destfile:执行数据输出文件的路径,默认为
jacoco.exec
。 - append:如果设置为
true
并且执行数据文件已存在,则覆盖数据将追加到现有文件中;如果设置为false
,则现有文件将被替换,默认为true
。 - includes/excludes:包含或排除执行分析的类名列表,支持使用通配符。默认值是 *,表示包含所有类。
- exclclassloader:排除执行分析的类加载器名称列表,可能在特殊框架冲突时需要。
- inclbootstrapclasses:是否对引导类加载器中的类进行增强,需要谨慎使用。
- inclnolocationclasses:是否对没有源位置的类进行增强,这些类通常在运行时生成。
- sessionid:会话标识符,与执行数据一起写入。
- dumponexit:如果设置为
true
,则在虚拟机退出时写入覆盖数据。 - output:覆盖率数据的输出方式。可以是 file(写入到文件),tcpserver(启动一个 TCP 服务器等待客户端连接),tcpclient(连接到一个 TCP 服务器)。
- address/port:用于TCP服务器tcpserver或客户端tcpclient模式的IP地址或主机名和端口。address默认值是 localhost。address=*:设置 TCP 服务器的地址为任意地址。
- classdumpdir:代理看到的所有类文件的转储位置,用于调试或动态创建的类。
- jmx:是否通过JMX暴露功能。
注意
如果已有的覆盖率文件被删除了,那么无论append
参数为 true 还是 false,生成的覆盖率文件都会是一样的。
这是因为 append 参数控制的是新的覆盖率数据是否被添加到已有的覆盖率文件中。如果
append=true,新的覆盖率数据会被添加到已有的覆盖率文件中。如果 append=false,新的覆盖率数据会覆盖已有的覆盖率文件。然而,如果已有的覆盖率文件被删除了,那么无论 append 参数的值是什么,JaCoCo
都会创建一个新的覆盖率文件,并将新的覆盖率数据写入这个新文件。所以,无论 append 参数为 true 还是
false,生成的覆盖率文件都会是一样的。
在 Kubernetes 环境中,每次 Pod 重新创建时,它都会有一个新的文件系统,旧的文件系统(包括其中的覆盖率数据)将会被丢弃。这意味着,即使你设置了 append=true,新的覆盖率数据也无法添加到旧的数据中,因为旧的数据已经被丢弃了。
如果你希望在 Pod 重新创建时保留覆盖率数据,你需要将覆盖率数据保存到一个持久化的存储中,例如一个持久化卷(Persistent
Volume)或者一个远程的存储服务。另一种方法是在 Pod 结束时,使用 kubectl cp 命令或者其他方法将覆盖率数据复制出来,然后在新的 Pod
启动时,再将这些数据复制回去。这样,即使 Pod 重新创建,你也可以保留覆盖率数据。
安全考虑
- 远程代理控制:
tcpserver
和tcpclient
模式以及JMX接口中,打开的端口和连接没有提供任何认证机制。在生产系统上运行JaCoCo时,确保不受信任的来源无法访问TCP服务器端口,或者JaCoCo TCP客户端只连接到受信任的目标,以防止应用程序的内部信息泄露或可能的拒绝服务攻击。
总结
JaCoCo提供了一种灵活且强大的方式来测量Java代码的覆盖率,通过代理机制可以轻松集成到现有的Java应用程序中。它支持多种输出方式,允许开发者根据需要选择最合适的覆盖数据收集方法。同时,JaCoCo的配置选项允许对覆盖数据收集过程进行精细控制,以满足不同的测试需求。然而,使用时需要注意安全性,特别是在开放网络环境中。
ref: https://www.eclemma.org/jacoco/trunk/doc/agent.html