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:
lein uberjar
, obtain some-client-0.0.0-standalone.jar
.java -jar some-client-0.0.0-standalone.jar
.some-client-0.0.1-standalone.jar
, copy it to some-client-0.0.0-standalone.jar
directory.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:
Having that define simlle upgrade scenario can be proposed:
In such a way meta application will be able to provide a new or updated functionality without restart. So you can:
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:
Second project provides Producer-Consumer example using clojure and OSGi:
Happy coding.
For reloading at runtime strictly from jar files you may need to look into OSGi class loaders.
For Clojure code you could start nrepl in your client that listens on a local port and then when you want to reload the code you connect to that port and make a call to load-file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With