The JVM specification defines two types of class loaders:starting the inside loader(Bootstrap)and user-defined loaders(user-defined class loader)。
A. ClassLoaderBasic Concepts
1. ClassLoadercategory
The class loader is used to load classes (class) into the JVM.
The JVM specification defines two types of class loaders:starting the inside loader(Bootstrap)and user-defined loaders(user-defined class loader)。
the JVM generates three Classloader:bootstrap ClassLoader, Extension ClassLoader, and Appclassloader at run time.Bootstrap is written in C + +, we do not see it in Java, is null, is the JVM's own class loader, used to load the core class library, such as java.lang.*.
Appclassloaderof theParentis aExtclassloader, whileExtclassloaderof theParentto beBootstrap ClassLoader.
Javaprovides an abstract classClassLoader, all user-defined class loaders are instantiated fromClassLoadersub-class. System Class Loaderis a special user-defined class loader,JVMthe user class is loaded by default when the programmer does not specifically specify the loader。 The System class loader can be obtained by means of the Classloader.getsystemclassloader () method.
Example 1, test the ClassLoader of the JVM you are using
public class LoaderSample1 {
public static void Main (string[] args) {
Class C;
ClassLoader cl;
CL = Classloader.getsystemclassloader ();
SYSTEM.OUT.PRINTLN (CL);
while (CL! = null) {
CL = Cl.getparent ();
SYSTEM.OUT.PRINTLN (CL);
}
try {
c = Class.forName ("Java.lang.Object");
CL = C.getclassloader ();
System.out.println ("Java.lang.Object s loader is" + cl);
c = Class.forName ("LoaderSample1");
CL = C.getclassloader ();
System.out.println ("LoaderSample1 s loader is" + cl);
} catch (Exception e) {
E.printstacktrace ();
}
}
}
Running results on my machine (Sun Java 1.4.2)
[Email protected]
[Email protected]
Null
Java.lang.Object ' s loader is null
LoaderSample1 ' s loader is [email protected]
The first line indicates that the System class loader instantiates its own class Sun.misc.launcher$appclassloader
The second line indicates that the parent of the System class loader is instantiated from class Sun.misc.launcher$extclassloader
The third line indicates that the parent of the System class loader parent is bootstrap
The four lines indicate that the core class Java.lang.Object is loaded by bootstrap
Line five indicates that the user class LoaderSample1 is loaded by the System class loader
two. Parent Delegation Model
Starting with version 1.2, Java has introduced a parental delegation model to better ensure the security of the Java platform.under this model, when a loader is requested to load a class, it first delegates its ownParentto load, ifParentcan be loaded, the class is returned with the correspondingClassobject, ifParentcannot be loaded, it is byParentthe requestor goes to load。
Figure 1 The parent delegation model
As shown in 1, the Loader2 parent is the Loader1,loader1 parent for System class loader. Assuming that loader2 is required to load class MyClass, under the parent delegation model, LOADER2 first requests Loader1 to load, Loader1 then requests the System class loader to load MyClass. If the system loader is able to load successfully, the reference of the class object corresponding to the MyClass is returned to Loader1,loader1 and the reference is returned to Loader2, which successfully loads the classes MyClass into the virtual machine. If the System class loader cannot load Myclass,loader1 will attempt to load MyClass, and if Loader1 cannot load successfully, LOADER2 will attempt to mount. If all the parent and loader2 itself cannot be loaded, the load fails.
If there is a successful load, the actual loaded class loader is called the definition class loader, all loaders that can successfully return the class object (including the definition class loader) are called the initial class loaders. As shown in 1, assuming that Loader1 actually loaded MyClass, then Loader1 is the MyClass definition class loader, loader2 and Loader1 as the initial class loader for MyClass.
It should be noted that class loader is an object whose parent-child relationship has no relation to the parent-child relationship of the class.
So why is the parent delegation model more secure?because under this model the user-defined class loader cannot load reliable classes that should be loaded by the father loader, thereby preventing unreliable or even malicious code from replacing the reliable code loaded by the Father loader. In fact, the writer of the class loader is free to choose not to delegate the request toParent, but as mentioned above, it poses a security problem.
three. Namespaces and their role
Each class loader has its own namespace, and the namespace consists of all classes that use this loader as the initiator class loader. The two classes of different namespaces are not visible, but as long as you get the reference of the class object corresponding to the classes, you can also access the classes of the other namespace.
Example 2 demonstrates how a class of a namespace uses a class of another namespace. In the example, LoaderSample2 is loaded by the System class loader, LoaderSample3 is loaded by a custom loader loader, two classes are not in the same namespace, But LoaderSample2 gets the reference of the class object corresponding to LoaderSample3, so it can access the public members of the LOADERSAMPL3 (such as age).
Example 2 access to classes of different namespaces
Import java.net.*;
Import java.lang.reflect.*;
public class LoaderSample2 {
public static void Main (string[] args) {
try {
String Path = System.getproperty ("User.dir");
Url[] US = {new URL ("file://" + path + "/sub/")};
ClassLoader loader = new URLClassLoader (US);
Class C = Loader.loadclass ("LoaderSample3");
Object o = c.newinstance ();
Field f = C.getfield ("Age");
int age = F.getint (o);
System.out.println ("Age was" + age);
} catch (Exception e) {
E.printstacktrace ();
}
}
}
public class LoaderSample3 {
static {
System.out.println ("LoaderSample3 Loaded");
}
public int age = 30;
}
Compilation: Javac Loadersample2.java; Javac Sub/loadersample3.java
Running: Java LoaderSample2
LoaderSample3 Loaded
Age is 30
As you can see from the running results, you can create objects in class LoaderSample3 in another namespace and have access to their public member age in LoaderSample2.
Run-time packages (Runtime package)
Classes belonging to the same package as defined by the same class loader make up the run-time package, deciding whether the two classes belong to the same run-time package, not only to see if their package names are the same, but also to see if the class loader is the same.only classes that belong to the same run-time package can access the classes and members that the package is visible to each other. Such restrictions prevent the user's own code from impersonating the core class library class to access the Core class library package visible members. (That is, if a class is loaded by two ClassLoader, but objects A and b of that class are created in two class loaders, respectively, because A and B are not within a classloader, they are not part of the same runtime package, so even if the package name class names are the same, they are not objects of the same class)Suppose that the user has defined a class java.lang.Yes himself and loaded it with a user-defined class loader, because the Java.lang.Yes and core class libraries java.lang.* loaded by different loaders, they belong to different run-time packages, So java.lang.Yes cannot access the members of the class's package visible in the core class library Java.lang.
Summary
namespaces do not completely prohibit the mutual access of classes belonging to different spaces, and the parental delegation model strengthensJavasecurity, the runtime package adds protection to the visible members of the package.
two. Extended ClassLoaderMethod
Our goal is to load a class from the local file system using our implemented class loader.in order to create our own class loader, we should extendClassLoaderclass, which is an abstract class. We create aFileclassloader extends ClassLoader. We need to coverClassLoaderin theFindclass (String name)method, which is obtained by the name of the classClassobject.
Public Class Findclass (String name)
{
byte[] data = loadclassdata (name);
Return defineclass (name, data, 0, data.length);
}
We should also provide a method loadClassData (String name) that returns the word of the class file by its name
section Array. Then we can return to the class object using the DefineClass () method provided by ClassLoader.
Public byte[] loadClassData (String name)
{
FileInputStream FIS = null;
byte[] data = null;
Try
{
FIS = new FileInputStream (new File (drive + name + fileType));
Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
int ch = 0;
while ((ch = fis.read ())! =-1)
{
Baos.write (CH);
}
data = Baos.tobytearray ();
} catch (IOException e)
{
E.printstacktrace ();
}
return data;
}
Original link: http://jamesdu.bokee.com/index.html
Reproduced ClassLoader principle