Clojure热代码交换uberjars / .classes [英] Clojure hot code swapping for uberjars/.classes

查看:165
本文介绍了Clojure热代码交换uberjars / .classes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. Make lein uberjar ,获取 some-client-0.0.0-standalone.jar

  2. 使用 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. 客户端接收更新到新版本所需的命令序列。

  6. (可选) some-client-0.0.0-standalone.jar 可以删除现在。


解决方案

插件框架方法



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





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


  1. 您有一个包含一些扩展点的元应用程序(:

     >更好的模块化OSGi等
    > * names
    > *没有单个命名空间池
    > *通过类找到的命名空间,因此跟踪类加载器和模块
    > *处理导入代理一个Class.forName栈走?

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


    1. clojure-osgi-utils

    2. clojure.osgi

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





    快乐编码。


    I want to have hot code swapping between project updates, but I haven't found any information about how to load .class files dynamically. More specifically, I want something like that:

    1. Make lein uberjar, obtain some-client-0.0.0-standalone.jar.
    2. Run it with java -jar some-client-0.0.0-standalone.jar.
    3. Make changes to project. Obtain new program version, some-client-0.0.1-standalone.jar, copy it to some-client-0.0.0-standalone.jar directory.
    4. Client receive sequence of commands needed to update to new version.
    5. (optional) Updates resources. Resources from old jar are no longer used.
    6. (optional) some-client-0.0.0-standalone.jar can be deleted now.

    解决方案

    Plug-in framework approach

    You've stated you want to have hot code swapping, but what you actually need is loosely coupled modules and ability to do resolve in run-time. Frankly speaking any plug-in framework may help, including mature OSGi (will be covered below).

    Since you are doing some kind of PoC I suggest to review the following example:

    1. you have a meta application with some extension points (metaphor explanation) defined
    2. functionality to be upgraded or replaced will be implemented as a loosely coupled modules (plug-ins)
    3. meta application performs resolve by request or automatically in order to find updated "functionality" (according to defined extension points)

    Having that define simlle upgrade scenario can be proposed:

    1. user uses an application
    2. user installs (copies) a JAR (other type of bundle) with new implementation of one or several extension points
    3. user triggers global system resolve or system scans for new updates or system performs resolve every tine user tries to access some piece of functionality

    In such a way meta application will be able to provide a new or updated functionality without restart. So you can:

    1. try use some simple java plug-in framework (like, for example, Java Simple Plugin Framework. 5 minutes and it works. No XML. This approach seems to be a little bit ugly
    2. use dynamic nature of clojure, as was suggested here

    You can also review and adopt Waterfront (Clojure based editor for Clojure) findings (it might be needed to enhance lifecycle management, etc)

    In terms of implementation, Waterfront is based on the context pattern. It allows event handlers to communicate in a functional (side-effect free) manner. On top of this there is a plugin-loader mechanism which loads the plugins that are specified in Waterfront's configuration file. This means that functionality can be easily added or removed (extremely useful when debugging!).

    OSGI approach

    As was suggested OSGi seems to be a good way to solve your problem. Please also note OSGi is good, mature and provides a lot stuff out of the box, but it is also somewhat complex:

    BTW, OSGi is a long-term goal for the clojure community. You can check 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?
    

    There are some solutions already available:

    1. clojure-osgi-utils
    2. clojure.osgi

    Second project provides Producer-Consumer example using clojure and OSGi:

    Happy coding.

    这篇关于Clojure热代码交换uberjars / .classes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆