Clojure热门代码交换为uberjars/.classes

des*_*esu 7 osgi clojure

我想有热代码项目更新之间的交换,但我还没有找到如何动态地加载.class文件的任何信息.更具体地说,我想要这样的东西:

  1. 制作lein uberjar,获得some-client-0.0.0-standalone.jar.
  2. 运行它java -jar some-client-0.0.0-standalone.jar.
  3. 对项目进行更改.获取新程序版本,some-client-0.0.1-standalone.jar将其复制到some-client-0.0.0-standalone.jar目录.
  4. 客户端接收更新到新版本所需的命令序列.
  5. (可选)更新资源.不再使用旧jar的资源.
  6. (可选)some-client-0.0.0-standalone.jar现在可以删除.

Ren*_*nov 5

插件框架方法

您已声明要进行热代码交换,但实际需要的是松散耦合的模块以及在运行时进行解析的能力.坦率地说,任何插件框架都可能有所帮助,包括成熟的OSGi(将在下面介绍).

在此输入图像描述

由于您正在进行某种PoC,我建议您查看以下示例:

  1. 你有一个meta应用程序,定义了一些扩展点(隐喻解释)
  2. 要升级或替换的功能将实现为松散耦合的模块(插件)
  3. 元应用程序按请求执行解析或自动执行以查找更新的"功能"(根据已定义的扩展点)

可以提出定义simlle升级方案:

  1. 用户使用应用程序
  2. 用户使用一个或多个扩展点的新实现来安装(复制)JAR(其他类型的包)
  3. 用户触发全局系统解析或系统扫描以获取新更新或系统执行解析每个用户尝试访问某些功能

通过这种方式,元应用程序将能够在不重新启动的情况下提供新的或更新的功能.所以你可以:

  1. 尝试使用一些简单的java插件框架(例如,Java Simple Plugin Framework.5分钟,它可以工作.没有XML.这种方法似乎有点难看
  2. 使用clojure的动态性质,如此处所示

您还可以查看并采用Waterfront(基于Clojure的Clojure编辑器)结果(可能需要加强生命周期管理等)

在实施方面,Waterfront基于上下文模式.它允许事件处理程序以功能(无副作用)方式进行通信.除此之外,还有一个插件加载器机制,用于加载Waterfront配置文件中指定的插件.这意味着可以轻松添加或删除功能(在调试时非常有用!).

OSGI方法

正如所建议的那样,OSGi似乎是解决问题的好方法.还请注意OSGi很好,很成熟并提供了很多开箱即用的东西,但它也有些复杂:

在此输入图像描述

顺便说一下,OSGi是clojure社区的长期目标.你可以查看Clojure Todo:

> better modularization for OSGi etc 
>  * names
>  * no single namespace pool
>  * namespaces found via classes, thus tracks classloader and modules 
>  * deal with import proxying a la Class.forName stack walk?
Run Code Online (Sandbox Code Playgroud)

有一些解决方案已经可用:

  1. Clojure的-OSGi的utils的
  2. clojure.osgi

第二个项目使用clojure和OSGi提供Producer-Consumer示例:

快乐的编码.


Art*_*ldt 2

为了在运行时严格从 jar 文件重新加载,您可能需要查看OSGi 类加载器。对于 Clojure 代码,您可以在客户端中启动 nrepl 来侦听本地端口,然后当您想要重新加载代码时,您可以连接到该端口并调用load-file