Java Dynamic Reload class
The project uses the mechanism of dynamic reload class, which is to allow some code to go online before the environment test, of course, this is a very bad test mechanism, I just came to this mechanism was surprised-how to run the test code on the environment online! Later, there are two reasons for doing this:
- Some code has no way to test locally, there is no local environment on the line
- We're weak to even a test machine (which is the point)
Since we don't even have a test machine, then I think our project is not really important to imagine, so test it!
Before the concept of ClassLoader, Google to an article, translated and made some additions, deepen the memory
Original address:
Reference Http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html#classloader
---------------------------------------------------
ClassLoader
As the name implies, ClassLoader is used to load class, and when a class is loaded, all classes referenced by this class are loaded, and the load is recursive, that is, if a references to b,b reference to C, B will also be loaded when a is loaded, and C will load when B is loaded. So recursion until all the required classes are loaded well.
Common ClassLoader:
Reference * Bootstrap class loader: The loader of the class that must be used to run the virtual runtime, such as Java.*. It is usually implemented in a virtual machine type with native code (such as C) and is represented in the system with NULL.
* Extension Class Loader: Responsible for loading the class in the Ext directory.
* Application Class Loader: Responsible for loading classes on classpath.
the agent hierarchy relationship of ClassLoader
ClassLoader is organized in a hierarchical relationship, and when you create a standard Java ClassLoader, you must provide a parent classloader. When a classloader needs to load a class, it first lets the parent ClassLoader load the class, and if the parent ClassLoader cannot load the class, then the current classloader will load itself.
ClassLoader the steps to load class:
- Check to see if this class has been loaded.
- If it has not been loaded, then let the parent ClassLoader try to load
- If the parent ClassLoader cannot load, then try to load with the current ClassLoader
The steps to load class from ClassLoader know that if you need to dynamically reload a class, your classloader must be different from the standard process described above, and the class that requires dynamic loading cannot be handed to the parent ClassLoader. Otherwise your own classloader will not have the chance to load this class (because normally the parent ClassLoader can always load into the class you requested).
So, if you need ClassLoader to reload a class, overriding the Findclass method is ineffective because Findclass does not execute until the parent ClassLoader fails to load
Java code
- First, check if the class has already been loaded
- Class C = findloadedclass (name);
- if (c = = null) {
- try {
- if (parent! = null) {
- c = Parent.loadclass (name, false);
- } Else {
- c = FINDBOOTSTRAPCLASS0 (name);
- }
- } catch (ClassNotFoundException e) {
- //If still not found, then invoke Findclass in order
- //To find the class.
- c = findclass (name);
- }
- }
You must override the LoadClass method to achieve the effect.
dynamically Reload Class
Java's built-in ClassLoader always checks to see if the class has been loaded before loading a class, and the class that has already been loaded does not load the second time. So to reload class, we need to implement our own classloader.
Another problem is that each loaded class needs to be linked (link), which is done by executing classloader.resolve (), which is final and therefore cannot be rewritten. The Resove () method does not allow a ClassLoader instance to link to a class two times, so when you need to reload a class, you need to re-add a new instance of your own classloader.
Just now, a class cannot be loaded two times by a ClassLoader instance, but can be loaded by different ClassLoader instances, which brings new problems:
Java code
- MyObject object = (MyObject)
- Myclassreloadingfactory.newinstance ("Com.jenkov.MyObject");
This code causes a classcastexception, because in a Java application, class is uniquely identified by its full name (package name + class name) and the ClassLoader that loads it. In the above code, the class of the object objects corresponding to the classes returned by the newinstance is distinguished from the class of the instance:
|
Name |
ClassLoader instances |
| The class of Object objects |
Com.jenkov.MyObject |
Appclassloader instances |
| Newinstance returns the class of the object |
Com.jenkov.MyObject |
customizing ClassLoader instances |
The solution is to use the interface or the parent class, just reload the implementation class or subclass.
Java code
- Myobjectinterface object = (myobjectinterface)
- Myclassreloadingfactory.newinstance ("Com.jenkov.MyObject");
- Myobjectsuperclass object = (myobjectsuperclass)
- Myclassreloadingfactory.newinstance ("Com.jenkov.MyObject");
In their own implementation of the ClassLoader, when the need to load myobjectinterface or Myobjectsuperclass, the agent to the parent ClassLoader to load.
Java_ dynamic Reload class mechanism