服务器上直接更新jar包中class文件

247 阅读1分钟

目前现状

  • 项目源码
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public RouterFunction<ServerResponse> routes() {
        return RouterFunctions.route()
                .GET("/hello", request -> ServerResponse.ok()
                        .contentType(MediaType.TEXT_PLAIN)
                        .body(Mono.just("Hello, WebFlux!"), String.class))
                .build();
    }

}
  • 请求结果
$ curl http://localhost:8080/hello
Hello, WebFlux!
  • 目标结果

修改请求地址 /hello 改为 /hello1

反编译class文件

查询 DemoApplication 路径

$ jar -tf demo-0.1-SNAPSHOT.jar | grep DemoApplication
BOOT-INF/classes/com/example/demo/DemoApplication.class

解压缩jar包

$ unzip demo-0.1-SNAPSHOT.jar

反编译DemoApplication.class文件

# 进入arthas控制台
java -jar arthas-boot.jar PID
# 进入arthas控制台后
$ sc *DemoApplication
com.example.demo.DemoApplication
com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$434130c6
Affect(row-cnt:2) cost in 31 ms.
$ jad --source-only com.example.demo.DemoApplication > DemoApplication.java
# 停止arthas
$ stop 
# 将class文件编译成base64
$ base64 DemoApplication.class
# 将class文件反编译成 class或java
$ base64 -d DemoApplication.txt DemoApplication.class

javac将java文件编译成class

# 将java文件放入jar解压后DemoApplication.class同级目录
mv DemoApplication.java ./BOOT-INF/classes/com/example/demo/
# 进入BOOT-INF/classes目录
cd ./BOOT-INF/classes
# javac 编译
javac -Djava.ext.dirs=../lib/ BOOT-INF/classes/com/example/demo/DemoApplication.java

jar包更新成新的class文件

# 查看当前class文件信息
$ jar -tvf demo-0.1-SNAPSHOT.jar | grep DemoApplication
3140 Mon Aug 19 19:44:04 CST 2024 BOOT-INF/classes/com/example/demo/DemoApplication.class

# 替换class文件,注意目录路径要和上面class路径一直,不可改变
$ jar -uvf demo-0.1-SNAPSHOT.jar BOOT-INF/classes/com/example/demo/DemoApplication.class 
正在添加: BOOT-INF/classes/com/example/demo/DemoApplication.class(输入 = 2902) (输出 = 1048)(压缩了 63%)

# 查看新的class文件信息
$ jar -tvf demo-0.1-SNAPSHOT.jar | grep DemoApplication
2902 Mon Aug 19 19:58:32 CST 2024 BOOT-INF/classes/com/example/demo/DemoApplication.class

重启项目

$ curl http://localhost:8080/hello
{"timestamp":"2024-08-19T09:02:25.614+00:00","path":"/hello","status":404,"error":"Not Found","message":null,"requestId":"e47147cd-1"}

$ curl http://localhost:8080/hello1
Hello, WebFlux!