14
votes

I have a Clojure project, and I'm using leiningen. I'm also using tools.namespace to reload Clojure code while running a REPL. If I want to include Java source in the project, can I recompile and reload it while the REPL is running? What is the most convenient/dynamic way of doing it? Can I do it so that it works well with tools.namespace?

5
Maybe add :aot :all in project.clj?halfelf
@halfelf that does not sound like what I want.oskarkv
I'm looking for the exact same thing. It'll be a huge win if this functionality is implemented. There is a javac function in github.com/technomancy/leiningen/blob/… that is included in leiningenzcaudate

5 Answers

7
votes

I'm answering my own bounty here but I did do a bit of work getting this up:

Use Vinyasa,

and here is a blog post:

Dynamic reloading of java code in emacs/nrepl

... actually... it's kinda not working anymore... you have to do back to the earlier versions in order to get the support.

6
votes

Nowadays (2016->) the better answer is to use Virgil. It watches and recompiles all Java code in your leiningen project automatically in the background, as opposed to Vinyasa's approach of invoking reimport.

3
votes

Spring-loaded or JRebel might be what you want. Have a look at https://github.com/spring-projects/Spring-loaded or http://zeroturnaround.com/software/jrebel/. They both provide an agent monitoring the filesystem for class file changes and update class definitions in the running JVM. I personally use Spring-loaded, but not yet together with tools.namespace. I guess the key to run them both is to make sure they do not conflict. So if you use Spring-loaded, it should be the only tool tracking class files and you better not use aot at all. If I remember correctly, tools.namespace discourages the use of aot anyways.

2
votes

Pure java way

public class MyClassFactory {
   public static MyClass newInstance() {
       URLClassLoader cl =
           new URLClassLoader(new URL[] {getMyClassPath()}) {

           public Class loadClass(String name) {
              if ("MyClass".equals(name))
                 return findClass(name);
              return super.loadClass(name);
          }
       };

     return (MyClass) cl.loadClass("MyClass").newInstance();
  }
}

by this way you can lead the class loader to load classes programmatically.

References

0
votes

See also the official JVM services loader

ServiceLoader