写点什么

Byteman 使用指南(五)

作者:FunTester
  • 2025-02-10
    河北
  • 本文字数:1998 字

    阅读完需:约 7 分钟

规则绑定

事件规范中包含一个绑定规范,用于在规则触发时计算并引用变量的值。这些绑定值会在每次规则触发时重新计算,并在测试规则条件之前使用。例如:


# 绑定示例RULE countdown at commitCLASS com.arjuna.wst11.messaging.engines.CoordinatorEngineMETHOD commitAT READ stateBIND engine:CoordinatorEngine = $0;     recovered:boolean = engine.isRecovered();     identifier:String = engine.getId(). . .ENDRULE
复制代码


在此示例中,变量 engine 绑定到触发规则的 commit 方法调用的接收者,该接收者通过 $0 参数引用。如果 commit 是静态方法,则引用 $0 会导致类型检查异常。方法的参数可以通过 $1, $2 等索引访问。声明 engine 时可以指定类型为 CoordinatorEngine,但这不是必须的,因为类型可以从 $0 的类型推断。


类似地,变量 recoveredidentifier 通过右侧表达式计算值。类型说明符是可选的,未指定时系统会自动推断其类型。对于不需要绑定变量的规则,可以使用特殊语法 BIND NOTHING,或直接省略 BIND 子句。

向下转型的规则绑定

绑定初始化不仅用于为计算的值引入变量,还可以执行向下转型(downcast),将通用类型值分配给更具体的子类类型的规则变量。例如:


# 向下转型示例RULE countdown at commitCLASS com.arjuna.wst11.messaging.engines.CoordinatorEngineMETHOD commitAT READ stateBIND engine:CoordinatorEngine = $0;     endpoint:javax.xml.ws.EndpointReference = engine.participant;     w3cEndpoint:javax.xml.ws.wsaddressing.W3CEndpointReference = endpoint. . .ENDRULE
复制代码


在此规则中,engine.participant 的值被绑定到变量 endpoint,其类型为 EndpointReference。随后,变量 w3cEndpoint 使用 endpoint 的值,并通过向下转型声明为 W3CEndpointReference 类型。这在其他规则赋值中可能导致类型错误,但在绑定初始化中是允许的,前提是转换合法。


字节码检查器在初始化时会验证类型转换是否有效,并在失败时抛出异常。例如,假设 CoordinatorEngine 的字段 participant 被声明为 W3CEndpointReference 类型,则上述绑定永远不会失败。


向下转型在需要处理通用类型(如 List)时特别有用。由于泛型类型信息在编译时会被擦除,字节码检查器无法直接识别其具体类型。例如,通过列表检索的值总是被视为 Object 类型。如果已知列表存储的是特定类型的值,可以通过 BIND 子句将其向下转型为具体类型。

规则表达式

事件绑定中等号右侧的表达式可以是 Byteman 支持的任何 Java 表达式,包括:


  • 绑定变量的引用。

  • 触发方法的接收者或参数的引用。

  • 触发点范围内局部变量的引用。

  • 特殊变量 $!$^$#$*$@$CLASS$METHOD 的引用。

  • 静态字段或实例字段的引用。

  • 原始字面量或数组字面量。

  • 方法调用(静态或实例)。

  • 内置操作调用。


表达式还可以由复杂组合构成,支持 Java 运算符,如 +, -, *, /, %, &&, ||, ==, !=, <, <= 等。三元运算符 ? : 也被支持。

特殊变量

  • $!:绑定触发点处的返回值,在 AT EXITAFTER INVOKE 规则中有效。

  • $^:绑定触发点处抛出的异常,在 AT THROWAT EXCEPTION EXIT 规则中有效。

  • $#:绑定为触发方法的参数数量。

  • $*:绑定为包含触发方法接收者和参数的 Object[] 数组。

  • $@:在 AT INVOKE 规则中有效,绑定为目标方法的接收者及调用参数数组。

  • $CLASS:绑定为触发规则的类的完全限定名。

  • $METHOD:绑定为触发规则的方法的完整签名。

  • $NEWCLASS:在 AT NEWAFTER NEW 规则中有效,绑定为新操作创建的类名。

规则条件

规则条件是布尔类型的表达式,用于决定规则是否触发。例如:


RULE countdown at commitCLASS com.arjuna.wst11.messaging.engines.CoordinatorEngineMETHOD commitAT READ stateBIND engine:CoordinatorEngine = $this;     recovered:boolean = engine.isRecovered();IF recovered. . .ENDRULE
复制代码


上述条件测试绑定变量 recovered 的值是否为 true。以下示例使用方法调用直接作为条件:


IF engine.isRecovered()
复制代码


如果相关字段直接存储布尔值,则条件可以简化为:


IF engine.recovered
复制代码


对于始终触发的规则,可以使用布尔字面量 true 作为条件。

规则动作

规则动作可以是返回值、抛出异常、或分号分隔的表达式序列。支持的主要类型包括:


  1. 返回动作(return

  2. 关键字 return 用于提前结束触发方法。如果方法非 void,需提供返回值。例如:


    DO return false
复制代码


  1. 抛出动作(throw

  2. 关键字 throw 可抛出运行时异常或触发方法声明的受检异常。例如:


    DO throw new RuntimeException("Error occurred")
复制代码


  1. 空动作(NOTHING

  2. 表示无具体动作。

内置调用

内置调用是由 Byteman 提供的工具方法,例如:


  • debug(String):打印调试信息。

  • killJVM():立即终止 JVM,模拟崩溃。


内置调用作为规则条件或动作的一部分执行,例如:


DO debug("killing JVM"), killJVM()
复制代码


Byteman 允许通过扩展 Helper 类添加自定义内置调用,为规则提供更多功能。

发布于: 刚刚阅读数: 5
用户头像

FunTester

关注

公众号:FunTester,800篇原创,欢迎关注 2020-10-20 加入

Fun·BUG挖掘机·性能征服者·头顶锅盖·Tester

评论

发布
暂无评论
Byteman 使用指南(五)_FunTester_InfoQ写作社区