我想在项目更新之间交换热代码,但我还没有找到有关如何动态加载.class文件的任何信息。 更具体地说,我想要这样的东西:
lein uberjar
,获取some-client-0.0.0-standalone.jar
。java -jar some-client-0.0.0-standalone.jar
运行它。some-client-0.0.1-standalone.jar
,将其复制到some-client-0.0.0-standalone.jar
目录。some-client-0.0.0-standalone.jar
现在可以删除。答案 0 :(得分:5)
插件框架方法
您已经声明要进行热代码交换,但实际需要的是松散耦合的模块以及在运行时进行解析的能力。坦率地说,任何插件框架都可能有所帮助,包括成熟的OSGi(将在下面介绍)。
由于您正在进行某种PoC,我建议您查看以下示例:
可以提出定义simlle升级方案:
通过这种方式,元应用程序将能够在不重新启动的情况下提供新的或更新的功能。所以你可以:
您还可以查看并采用Waterfront(基于Clojure的Clojure编辑器)结果(可能需要加强生命周期管理等)
在实施方面,Waterfront基于上下文 图案。它允许事件处理程序在功能中进行通信 (无副作用)方式。最重要的是有一个插件加载器 加载Waterfront中指定的插件的机制 配置文件。这意味着可以轻松添加功能 或删除(在调试时非常有用!)。
OSGI方法
正如所建议的那样,OSGi似乎是解决问题的好方法。请注意OSGi是好的,成熟的,并提供了很多开箱即用的东西,但它也有点复杂:
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?
已有一些解决方案可用:
第二个项目使用clojure和OSGi提供Producer-Consumer示例:
快乐的编码。
答案 1 :(得分:2)
为了在运行时严格从jar文件重新加载,您可能需要查看OSGi class loaders。
对于Clojure代码,您可以在客户端启动nrepl来侦听本地端口,然后当您想要重新加载连接到该端口的代码并调用load-file
时