|
|
|
|
|
|
|
|
|
在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 <hashcode>`
|
|
|
|
|
|
|
|
|
|
```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 <hashcode>`是动态变化的。
|
|
|
|
|
|
|
|
|
|
### 获取静态类的静态字段
|
|
|
|
|
|
|
|
|
|
获取`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
|