大多数JVM具备Java的HotSwap特性,大部分开发者认为它仅仅是一个调试工具。利用这一特性,有可能在不重启Java进程条件下,改变Java方法的实现。典型的例子是使用IDE来编码。然而HotSwap可以在生产环境中实现这一功能。通过这种方式,不用停止运行程序,就可以扩展在线的应用程序,或者在运行的项目上修复小的错误。这篇文章中,我将演示动态绑定、应用运行期代码变化进行绑定、介绍一些工具API以及ByteBuddy库,这个库提供了一些API代码改变更方便。
假设有一个正在运行的应用程序,通过校验HTTP请求中的X-Priority头部,来执行服务器的特殊处理。该校验使用下面的工具类来实现:
classHeaderUtility{staticbooleanisPriorityCall(HTTPServletRequestrequest){returnrequest.getHeader("X-Pirority")!=null;}}
你发现错误了吗?这样的错误很常见,尤其是在测试代码中常量值分解为静态字段重用。在不太理想的情况下,这个错误只会在产品被安装的时候才被发现,其中头通过另外一个应用生成并没有拼写错误。
修复这样的错误并不难。在持续交付的时代,重新部署一个新的版本只需要点击一下按钮。但在其他情况下,变更可能就不是那么简单了,重新部署过程可能比较复杂,其中停机是不允许的,带着错误运行可能会比较好。但HotSwap给我们提供了另外一种选择:在不重启应用的前提下进行小幅改动。
AttachAPI:使用动态附件来渗透另外一个JVM为了修改一个运行中的Java程序,我们首先需要一种可以同处在运行状态的JVM进行通信的方式。因为Java的虚拟机实现是一个受到管理的系统,因此拥有进行这些操作的标准API。提问中涉及到的API被称作attachmentAPI,它是官方Java工具的一部分。使用这个由运行之中的JVM所暴露的API,能让第二个Java进程来同其进行通信。
事实上,我们已经用到了该API:它已经由诸如VisualVM或者JavaMissionControl这样的调试和模拟工具进行了应用。应用这些附件的API并没有同日常使用的标准JavaAPI打包在一起,而是被打包到了一个特殊的文件之中,叫做tools.jar,它只包含了一个虚拟机的JDK打包发布版本。更糟糕的是,这个JAR文件的位置并没有进行设置,它在Windows、Linux,特别是在Macintosh上的VM都存在差别,不光文件的位置,连文件名也各异,有些发行版上就被叫做classes.jar。最后,IBM甚至决定对这个JAR中包含的一些类的名称进行修改,将所有北京中科医院诈骗曝光吡美莫司乳膏价格