之前已经写过一篇关于class的动态替换博客,今天我们来介绍一下如何用springloaded进行jar&class的动态替换。

首先说一下实验过程,结合了目前我正在做的项目,这个项目是一个前置系统,分别对接银联和核心系统。项目一开始由一个jar包组成,逻辑上可以分为3层:分发层,业务处理层,dao层(数据库操作相关),所有的class文件最后都在jar包中,运行时,只要启动这个jar包就行了,它是一个进程,会启动一个监听端口用来接收银联发送过来的报文。

这样做的缺点:后期你要修改代码,哪怕只有一行代码修改,你也要重新打包成jar包,kill掉正在运行的进程,然后重新启动!一开始对于我这种菜鸟,除了觉得这样做很麻烦之外,其他也没有觉得什么。后来,仔细一分析,在生产上运行,你停服务,是一件不可思议的事,因为所有的交易都要停止,像对于支付这样的交易,那影响就太大了!

所以,自然想到热部署方案,热部署网上也有一些相关的博客。但基本都不太“正规”,即都是那种简单的例子,看起来就不大可行。其中比较多的是自己定义classload来重新加载class文件,而且我看那些方法中路径和要重新加载的class文件都是写死的,这也太。。。当然,也有我觉得比较高大上的方法,就是将现在的系统改造成微服务架构,对于业务上独立的交易都改造成一个个微服务,那要卸载服务,重新部署服务自然都不在话下。不得不说,这确实是一个比较好的方法,但工作量和难度都是比较高的,想来想去,暂时不考虑,但会作为知识储备来学习,在适当的时间再来改造,因为这是趋势!

直到前几天,我偶然发现一个关于springloaded的帖子,这种方法比较简单,而且从名字可以看成,它是spring旗下的一个项目,应该来说还是比较可靠的,所以就试着用这个方法来进行改造,改造的方法也比较简单。

首先,我们要将jar包中的一些业务相关的代码从jar包中抽离出来,具体拆分的方法可以为,基本不需要修改的代码或者框架型的代码放在jar包中,而后期需要经常修改的代码从jar包冲分离出来。如下图:

所有的业务相关的代码(class文件)都放在business文件夹下,具体做法是创建了一个新的工程,然后现有的工程会依赖这个新的工程。同时,可以看到相关的配置文件我们也从jar包中分离出来,比如mybatis文件夹中放的是和数据库操作相关的文件。

我们在libs文件夹中放入

然后,输入命令:

这里插播一下,一开始我是上面这种写法,但是发现jar替换时不起任何效果,后来我想会不会是顺序的问题,我把-jar后面的参数移到最后面,发现这时候起作用了:

然后参数verbose可以省略,因为加上这个参数,日志中会有很多详细的信息,生产上不太方便查看,测试的时候可以加上。

我们发起一笔报文,前置系统运行结果如下:

我们对这个交易的代码进行修改,把“协议支付签约触发短信”这几个字去掉,然后保存,用这个class文件替换原先的class文件

可以看到,在不用停程序的情况下,运行结果已经改变了,基本达到我们的需求。

接下来的话就是,如果jar包里面的代码有修改,那就重新打包来替换旧的jar包,与替换class文件类似,我试了一下,同样是可以的。

2018-07-25更新

今天我在生产上试了一种情况,发现更换了class没有用,比如:a.jar直接调用了b.class,而b.class又调用了c.class,现在替换了c.class文件,发现不起作用。我们上面的例子是替换了b.class文件起作用。只有重启,c.class文件才起作用。这个问题后续值得继续关注!

利用springloaded进行java jar&class的动态替换的更多相关文章

  1. 利用springloaded进行java class动态替换

    我们知道对于一个java文件,如Test.java,首先需要通过javac命令(javac Test.java)进行编译,生成class文件,再将class文件在jvm上进行加载运行,也就是java命 ...

  2. 【java】 linux下利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...

  3. 使用C#利用cmd来调用java jar包获取其中的数据

    其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...

  4. java -jar参数运行方式设置classpath

    转载自:https://www.cnblogs.com/aggavara/archive/2012/11/16/2773246.html 当用java -jar yourJarExe.jar来运行一个 ...

  5. Java安全之Javassist动态编程

    Java安全之Javassist动态编程 0x00 前言 在调试CC2链前先来填补知识盲区,先来了解一下Javassist具体的作用.在CC2链会用到Javassist以及PriorityQueue来 ...

  6. 【hadoop2.6.0】利用Hadoop的 Java API

    Hadoop2.6.0的所有Java API都在 http://hadoop.apache.org/docs/r2.6.0/api/overview-summary.html 里. 下面实现一个利用J ...

  7. -Xbootclasspath参数、java -jar参数运行应用时classpath的设置方法

    当用java -jar yourJarExe.jar来运行一个经过打包的应用程序的时候,你会发现如何设置-classpath参数应用程序都找不到相应的第三方类,报ClassNotFound错误.实际上 ...

  8. 利用sfntly的sfnttool.jar提取中文字体

    雨忆博客中提到了sfntly(具体介绍可以看:https://code.google.com/p/sfntly/),利用其中sfnttool.jar就可以提取只包含指定字符的字体,如果想在页面中通过@ ...

  9. 【项目分析】利用C#改写JAVA中的Base64.DecodeBase64以及Inflater解码

    原文:[项目分析]利用C#改写JAVA中的Base64.DecodeBase64以及Inflater解码 最近正在进行项目服务的移植工作,即将JAVA服务的程序移植到DotNet平台中. 在JAVA程 ...

随机推荐

  1. 如何将极客时间课程制作成kindle电子书

    订阅了几个极客时间的专栏,一直没有时间去看. 最近,想着如果把内容制作成电子书,利用上下班时间学习一下,岂不是很方便? 在网上搜到一个很好用的开源软件,几分钟就可以把极客时间的专栏做成电子书,简直太棒 ...

  2. docker基本命令使用

    学会使用docker命令帮助 docker help 子命令 查看docker镜像 docker images 搜索镜像 docker search 镜像名 下载镜像 docker pull 镜像名 ...

  3. ClassNotFoundException与NoClassDefFoundError异常

    方法 loadClass()抛出的是 java.lang.ClassNotFoundException异常(一般是jar冲突或者没有引入jar):方法 defineClass()抛出的是 java.l ...

  4. mysql 远程备份

    #远程备份./innobackupex --defaults-file=/etc/my.cnf --no-timestamp --user xxx --host 192.168.1.123 \--pa ...

  5. SQL注入检测

    目前只支持单个对象,不支持对象中包含对象 /// <summary> /// 检查SQL中的非法字符 /// </summary> public class SQLInject ...

  6. select函数总结

    阻塞方式block,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回.使用Select就可以完成非阻塞non-block,就是进程或线程执 ...

  7. Python + Robot Framework 环境搭建

    一.Python 安装 说明:由于RIDE是基于python2.x开发,后期未做python3.x兼容,所以这里安装python2.7. 链接: https://pan.baidu.com/s/1yf ...

  8. android 开发 View _16 自定义计步器View、自定义柱状图View

    /** *@content:实现计步的环形View *@time:2018-7-30 *@build: */ public class CountStepsAnnularView extends Vi ...

  9. 分享下自己写的一个微信小程序请求远程数据加载到页面的代码

    1  思路整理 就是页面加载完毕的时候  请求远程接口,然后把数据赋值给页面的变量 ,然后列表循环 2 js相关代码  我是改的 onload函数 /** * 生命周期函数--监听页面加载 */ on ...

  10. 文件上传:swfupload.js、blueimp-file-upload

    一.swfupload 1.下载swfupload http://code.google.com/p/swfupload/ 2. 3.API  http://www.cnblogs.com/henw/ ...