I've been reading code and documentation to try to understand how class reloading works in clojure. According to many websites, such as http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html , whenever you load a class essentially you obtain the bytecode (via any data mechanism), convert the bytecode into an instance of class Class (via defineClass), and then resolve (link) the class via resolveClass. (Does defineClass implicitly call resolveClass?). Any given classloader is only allowed to link a class once. If it attempts to link an existing class, it does nothing. This creates a problem since you cannot link a newly instantiated class, therefore you have to create a new instance of a classloader everytime you reload a class.
Going back to clojure, I tried examining the paths to load classes.
In clojure, you can define new classes in multiple ways depending on what you want:
Anonymous Class: reify proxy
Named Class: deftype defrecord (which uses deftype under the hood) gen-class
Ultimately, those codes point to clojure/src/jvm/clojure/lang/DynamicClassLoader.java
where DynamicClassLoader/defineClass creates an instance with super's defineClass and then caches the instance. When you want to retrieve the class, clojure load with a call to forName which calls the classloader and DynamicClassLoader/findClass, which first looks in the cache before delegating to the super class (which is contrary to the way most normal classloaders work, where they delegate first, than try it themselves.) The important point of confusion is the following: forName is documented to link the class before it returns but this would imply you can not reload a class from the existing DynamicClassLoader and instead need to create a new DynamicClassLoader, however I don't see this in the code. I understand that proxy and reify define anonymous classes, so their names are different thus can be treated as if its a different class. However, for the named classes, this breaks down. In real clojure code, you can have references to the old version of the classes and references to the new version of the classes simultaneously, but attempts to create new class instances will be of the new version.
Please explain how clojure is able to reload classes without creating new instances of DynamicClassLoader, if I can understand the mechanism to reload classes, I would like to extend this reloading functionality to java's .class files I may create using javac.
Notes: This question refers to class RELOADING, not simply dynamic loading. Reloading means that I have already interned a class but want to intern a new updated version of that instance.
I want to reiterate, that its not clear how clojure is able to reload deftype defined classes. Calling deftype eventually leads to a call to clojure.lang.DynamicClassLoader/defineClass. Doing this again leads another call to defineClass, but doing this manually results in a Linkage Error. What is happening underneath here that allows clojure to do this with deftypes?