远程执行小工具

来源:互联网 发布:python安装完怎么用 编辑:程序博客网 时间:2024/05/12 11:33
   今天想给项目写个远程执行的小工具
1.客户端动态编译要远程执行的代码
2.通过网络将编译好的字节码传输到服务端
3.服务端留一个类装载器的接口
4.对客户端传输过来的字节码做一定修改(复杂了的不好改,修改常量池还是不难实现的,比如需要输出信息到客户端,却又想用System.out输出,修改常量池就好了,不然System.out只能输出在服务端)
5.用自定义的ClassLoader将要执行的类装载到jvm,然后执行,输出信息返回给客户端

这个工具类还是比较强大的(不过也很危险,看怎么用了),可以看到服务端的任何类的变量,也可以执行清除缓存之类的操作。

以前写过这种小玩意儿,不过是在有web容器的环境下,
现在的项目是基于netty的长连接应用,不过也好搞定,把原来代码拿来改了个把小时搞定

首先写个netty server用来接收要执行的字节码(它要跟随应用Server一同启动,也就是说同jvm)
代码太多容易打乱思路,只贴出主要代码(decode):
Java代码 复制代码 收藏代码
  1. class HotSwapPipelineFactory implements ChannelPipelineFactory {
  2. private SimpleChannelHandler messageReceivedHandler =new SimpleChannelHandler() {
  3. @Override
  4. public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
  5. byte[] classByte = (byte[]) e.getMessage();// decode后的字节码byte数组
  6. // execute内部用自定义ClassLoader加载进jvm然后通过反射执行,返回值为一个String,是返回给客户端的信息,这部分代码就不贴出来了
  7. String resultMsg = JavaClassExecuter.execute(classByte);
  8. byte[] resultByte = resultMsg.getBytes(Charset.forName(Constants.UTF8_CHARSET));
  9. ChannelBuffer buffer = ChannelBuffers.buffer(resultByte.length);
  10. buffer.writeBytes(resultByte);
  11. e.getChannel().write(buffer);
  12. }
  13. };
  14. @Override
  15. public ChannelPipeline getPipeline() throws Exception {
  16. return addHandlers(Channels.pipeline());
  17. }
  18. public ChannelPipeline addHandlers(ChannelPipeline pipeline) {
  19. if (null == pipeline) {
  20. return null;
  21. }
  22. // 这个decoder主要应对消息不完整的情况,虽然是小工具也认真对待吧
  23. pipeline.addLast("hotSwapDecoder", new FrameDecoder() {
  24. @Override
  25. protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)throws Exception {
  26. if (buffer.readableBytes() >= 4) {
  27. buffer.markReaderIndex(); // 标记ReaderIndex
  28. int msgBodyLen = buffer.readInt(); // 前四个字节存放消息(字节码)的长度
  29. if (buffer.readableBytes() >= msgBodyLen) {
  30. ChannelBuffer dst = ChannelBuffers.buffer(msgBodyLen);
  31. buffer.readBytes(dst, msgBodyLen);
  32. return dst.array(); // 这就是完整的字节码byte数组了
  33. } else {
  34. buffer.resetReaderIndex();
  35. return null;
  36. }
  37. }
  38. return null;
  39. }
  40. });
  41. pipeline.addLast("hotSwapHandler", messageReceivedHandler);
  42. return pipeline;
  43. }

原创粉丝点击