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

时间:2013-02-28 21:11:59

标签: clojure osgi

我想在项目更新之间交换热代码,但我还没有找到有关如何动态加载.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现在可以删除。

2 个答案:

答案 0 :(得分:5)

插件框架方法

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

enter image description here

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

  1. 您的元应用程序包含一些扩展点(metaphor explanation)已定义
  2. 要升级或替换的功能将实现为松散耦合的模块(插件)
  3. 元应用程序按请求执行解析或自动执行以查找更新的“功能”(根据已定义的扩展点)
  4. 可以提出定义simlle升级方案:

    1. 用户使用应用程序
    2. 用户安装(复制)带有一个或多个扩展点的新实现的JAR(其他类型的包)
    3. 用户触发全局系统解析或系统扫描以获取新更新或系统执行解决每个用户尝试访问某些功能
    4. 通过这种方式,元应用程序将能够在不重新启动的情况下提供新的或更新的功能。所以你可以:

      1. 尝试使用一些简单的java插件框架(比如,Java Simple Plugin Framework. 5 minutes and it works. No XML.这种方法似乎有点难看
      2. 使用clojure的动态特性,如建议here
      3. 您还可以查看并采用Waterfront(基于Clojure的Clojure编辑器)结果(可能需要加强生命周期管理等)

          

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

        OSGI方法

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

        enter image description here

        BTW,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?
        

        已有一些解决方案可用:

        1. clojure-osgi-utils
        2. clojure.osgi
        3. 第二个项目使用clojure和OSGi提供Producer-Consumer示例:

          快乐的编码。

答案 1 :(得分:2)

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