在Arthas里,有一个单独的`ognl`命令,可以动态执行代码。 ### 调用static函数 `ognl '@java.lang.System@out.println("hello ognl")'`{{execute T2}} 可以检查`Terminal 1`(不是arthas的Terminal 2)里的进程输出,可以发现打印出了`hello ognl`。 ### 查找UserController的ClassLoader `sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash`{{execute T2}} ```bash $ sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash classLoaderHash 1be6f5c3 ``` 注意hashcode是变化的,需要先查看当前的ClassLoader信息,提取对应ClassLoader的hashcode。 如果你使用`-c`,你需要手动输入hashcode:`-c ` ```bash $ ognl -c 1be6f5c3 @com.example.demo.arthas.user.UserController@logger ``` 对于只有唯一实例的ClassLoader可以通过`--classLoaderClass`指定class name,使用起来更加方便: ```bash $ ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @org.springframework.boot.SpringApplication@logger @Slf4jLocationAwareLog[ FQCN=@String[org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog], name=@String[org.springframework.boot.SpringApplication], logger=@Logger[Logger[org.springframework.boot.SpringApplication]], ] ``` `--classLoaderClass` 的值是ClassLoader的类名,只有匹配到唯一的ClassLoader实例时才能工作,目的是方便输入通用命令,而`-c `是动态变化的。 ### 获取静态类的静态字段 获取`UserController`类里的`logger`字段: `ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @com.example.demo.arthas.user.UserController@logger`{{execute T2}} 还可以通过`-x`参数控制返回值的展开层数。比如: `ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -x 2 @com.example.demo.arthas.user.UserController@logger`{{execute T2}} ### 执行多行表达式,赋值给临时变量,返回一个List `ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'`{{execute T2}} ```bash $ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}' @ArrayList[ @String[/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre], @String[Java(TM) SE Runtime Environment], ] ``` ### 更多 在Arthas里`ognl`表达式是很重要的功能,在很多命令里都可以使用`ognl`表达式。 一些更复杂的用法,可以参考: * OGNL特殊用法请参考:https://github.com/alibaba/arthas/issues/71 * OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html