Do we need custom ClassLoader?
One reason: If we customize ClassLoader, we can control the JVM loading action.
The above says that a class logo is due to the Package ClassName. For all implementation Java.IO.
SERIALIZABLE interface class, by
SerialVersionuid Management These types of versions (RMI, JNDI, have such IDs in Security). It expressed 64-bit HASH (due to ClassName, FileD, Method). Technically, if ClassName, Field, Mehtod is the same, it will be considered as the same version.
Suppose there is such a situation, we have to write a Java execution engine (such as: use a RMI to release a server-side program, execute the client's interface), since it is necessary to execute, the engine must implement the interface with the client specific task (here Taskintf). One, the task is submitted to the execution engine, the first thing for Server is to load all the code to be executed. Suppose different terminals are submitted to different code. And all the same package name, and the same class name. Can the server discriminates the execution request submitted by that client?
Now there is a problem: if the server is executed in one execution program to submit the same version of the code, how to make the client get expected results?
Don't think this is very simple, let's build a RMI to play first. See what the result will be.
The answer is in this article (I want to know at this time :)
The local file is shown below.
Figure 2 Program directory structure (including code in this article).
In the Samepath directory, there are two version.version.class, they have the same name class name, the only difference is.
The method in the V1 directory is:
Public void fx () {log ("this =" this "; version.fx (1).");}
The method in the V2 directory is:
Public void fx () {log ("this =" this "; version.fx (2).");}
Execute a look:
Set classpath =.;% current_root% / v1;% current_root% / v2% java_home% / bin / java test results as follows
Figure 3. ClassPath's catalog is set to V1
Switch to
Set classpath =.;% current_root% / v2;% current_root% / v1% java_home% / bin / java test results as follows:
Figure 4. ClassPath directory is set to V2
Obviously, the above example can be found in ClassPath. If we put V1, V2's Version.Version. Customized. And put them into a MyExtension.jar package, put it in a java.ext.dirs directory. . At this time, it is loaded via EXTCLASSLOADER, not AppClassLoader.
The result will be below:
Figure 5. AppClassLoader and ExtClassLoader
Note Sun.Misc.launcher $EXTClassLoader@a9c85c is loaded with ExtClassLoader.
Continue to look down, another example. An example in the DIFFERENTVERSIONS directory, contains an execution engine such as the RMI ServerIMPL. The Client implemented a Common.TaskIntf interface. Two client.taskimpls are as follows: Static {log ("Client.taskimpl.class.getClassLoader (V1):" Taskimpl.class.getClassLoader ());} public void execute () {log ("this =" THIS "; execute (1)");
The other is:
Static {log ("Client.taskimpl.class.getClassLoader (V1):" TaskImpl.class.getClassLoader ());} public void execute () {log ("this =" this "; Execute (2)" }
This is to be executed (the order is casual, where% current_root% / client2 is placed in front):
ClassPath =% current_root% / common;% current_root% / server;% current_root% / client2;% current_root% / client1% java_home% / bin / java server.server
Start Server ..
Submit two Client to the server, (even if the client is written in the program, the client is shown, respectively, as shown in Figure 6.)
Figure 6. Execution Engine Server Console
Look at the following two figures (Figures 7 and 8), respectively, the Client end is performed.
Figure 7. Execution Engine Client 1 Console
Figure 8. Execution Engine Client 2 Console
Throughout the above three execution results, it is found that because the server is started to use AppClassLoader. So, no matter how it is loaded, it is client2 (because Client2 ClassPath is more in the order),
Here, the Client1 is very depressed, it performs clearly that EXECUTE (1) is sent to the server side through RMI to execute (2) ..
It is worth noting that after the client1, Client2 is sent to the server execution, the server-side record is: client.taskimpl.class.getClassLoader (V2): sun.misc.lanchor @ AppClassLoader @ xxxx zhiz only executed once. And this=Client.taskimpl@xxxxx execute (2); executed twice
It has already been said, and for a ClassLoader, the same page classname can only define a class, and different ClassLoad will define different Class if loading the same page.classname.
Here, I found out that it seems not easy to solve the problem. (.
How do you solve it? The answer is --- use custom ClassLoader .. If you wait, please see (the code in DifferentVersionsPush in the catalog)
Obviously, we must have a custom ClassLoader.