# 远程类更新
首先感谢 Alibaba 开源的 Java 诊断工具 Arthas,提供了核心功能。arthas yyds
然后,这是基于个人工作流,设计的一个用于减少更新远程代码所耗费的时间的功能。目前在功能实现上还有许多不足,交互操作、信息提示也是自己琢磨的,操作起来如果觉得别扭,欢迎通过 Github 提供宝贵意见。
# 使用场景
- 平时远程服务器代码调试,Java 代码需要加日志或者修改部分代码时
# 外部工具
远程类更新是借助阿里的 Arthas 工具完成的,实际使用之前,可以通过插件的上传按钮,将工具包上传到服务器的 /tmp/EasyDeploy
目录。
# 使用方法
远程类更新的入口在编辑器的右击菜单中,该功能只支持对 Java 文件操作。在右击菜单中选择 Remote Class Retransform
,会跳出一个操作窗口。
每个项目在初次使用的时候,会跳出一个选择目标服务器的窗口,先选择一个服务器。选择服务器之后,会进行服务器的连接,然后进行以下操作
- 检查服务器连接是否可用
- 服务器信息正确的情况下,获取当前服务器的 Java 程序
- 检查服务器是否有 Arthas 工具包,如果没有,可以通过窗口的上传按钮进行上传。
在前面三步准备完成的情况下,会要求选择一个远程 Java 程序进行端口绑定,这个端口是用来和 Arthas 交互的。如果选中的程序没有和端口进行绑定,则端口旁边的图标会呈断开状态,可以点击 Attach Process
按钮进行绑定。
经过上面的步骤之后,Arthas 已经和远程目标程序绑定了,之后可以点击 Retransform
按钮进行类更新。类更新的步骤分为
- 编译本地代码(目前还没发现怎么编译单个文件)
- 编译完成后,上传对应的 class 文件到远程服务器
- 通过 Arthas 交互端口,向 Arthas 发送
retransform
指令
成功后会有气泡信息提示。
# 功能限制
正如开头所说,这是借助 Arthas 的 retransform 命令完成的,所以有必要知道什么情况下不适合使用。
- 不允许新增加 field/method
- 正在跑的函数,没有退出不能生效,比如下面新增加的
System.out.println
,只有run()
函数里的会生效
public class MathGame {
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
while (true) {
game.run();
TimeUnit.SECONDS.sleep(1);
// 这个不生效,因为代码一直跑在 while里
System.out.println("in loop");
}
}
public void run() throws InterruptedException {
// 这个生效,因为run()函数每次都可以完整结束
System.out.println("call run()");
try {
int number = random.nextInt();
List<Integer> primeFactors = primeFactors(number);
print(number, primeFactors);
} catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 可能遇到的问题
下面的问题是我使用过程中遇到且暂时没有解决头绪的问题
第一次更新的时候,编译失败,报了很多奇怪的错误?
可以先自己将整个项目编译一遍,比如使用侧边栏 maven 的 compile 功能,编译完后续应该就不会报错了。之前我遇到的时候,编译一遍就没再出现了