Java class loader (advanced tutorial)

Source: Internet
Author: User

Let's talk about parent
Delegation) Mechanism
In the parent delegation mechanism, each loader forms a tree structure according to the parent-child relationship. Apart from the root loader, other class loaders have only one parent loader.
Assume loader2's father is loader1, and loader1's father is the system class loader. Assume that the Java program requires loader2 to load the sample class. The Code is as follows:

Class sampleclass = loader2.loadclass ("sample ");

Loader2 first checks whether the sample class has been loaded from its namespace. If it has been loaded, it returns a reference to the class object representing the sample class.

If the sample class has not been loaded, loader2 first requests loader1 for loading, loader1 requests the system class loader for loading, and the system class loader requests the extended Class Loader for loading, the extension class loader then requests the root class loader for loading. If neither the root loader nor the extension loader can be loaded, the system loader attempts to load the file. If the file can be loaded successfully, then, the reference of the Class Object corresponding to the sample class is returned to loader1, and loader1 is returned to loader2, so that the sample class is successfully loaded into the virtual machine.
If the system class loader cannot load the smaple class, loader1 tries to load the sample class. If loader1 cannot be loaded successfully, loader2 tries to load the class. If neither the parent loader nor loader2 can be loaded, A classnotfoundexception exception is thrown.

What are the advantages of the parent delegation mechanism?
The advantage of the parent entrusting mechanism is that it can improve the security of the software system. This mechanism makes it impossible for a custom class loader to load reliable classes that should be loaded by the parent loader, this prevents unreliable or even malicious code from replacing the reliable code loaded by the parent loader.
For example, the Java. Lang. Object Class is always loaded by the root class loader (bootstrap), and no other user-defined class loaders can load malicious code.
Java. Lang. Object Class.

There are several important concepts that need to be understood. (Security-related)
1. namespace
Each class loader has its own namespace, which consists of the loader and all the classes loaded by the parent loader.
In the same namespace, two classes with the same full name (including the package name of the class) are not displayed. In different namespaces,
There may be two classes with the same full name (including the package name of the class.

2. runtime package
A runtime package consists of classes loaded by the same class loader that belong to the same package. Determines whether the two classes belong to the same runtime package, not only
It depends on whether the package names are the same and whether the class loaders are the same. Only the classes that belong to the same runtime package can access and be visible to each other (that is, the default access level)
. This restriction prevents custom classes from impersonating the class of the core class library and accessing the visible members of the core class library. Assume that you have defined a class
Java. lang. spy, which is loaded by the user-defined class loader due to Jang. lang. spy and core class library Java. lang. * loaded by different loaders, which belong to different operations
So java. Lang. Spy cannot access visible members in the core class library java. lang package.

Create a custom Class Loader
To create your own class loader, you only need to extend the java. Lang. classloader class and overwrite its findclass (string
This method returns a reference to the corresponding class object based on the class name specified by the parameter.
Package com. jfans;

Import java. Io. bytearrayoutputstream;
Import java. Io. file;
Import
Java. Io. fileinputstream;
Import java. Io. ioexception;

Public class myclassloader extends classloader
{
 
// Specify a name for the Class Loader. In this example, it is only used to distinguish different loader objects.
Private string
Name;
Private string Path = "D ://";
Private final string filetype =
". Class ";
 
Public myclassloader (string name)
{
Super ();
This. Name = Name;
}

Public myclassloader (classloader parent, string name)
{
Super (parent );
This. Name = Name;
}

Public String getpath (){
Return path;
}

Public void setpath (string path ){
This. Path =
Path;
}
 
 
@ Override
Public String tostring (){
Return
This. Name;
}
 
// Customize private methods
Private byte [] loadclassdata (string
Name) throws classnotfoundexception {
Fileinputstream FCM = NULL;

Byte [] DATA = NULL;
Bytearrayoutputstream baos = NULL;


Try {
// Replace "." In the Name string with "/" to convert the package name in the class to the path name

// For example, if the name is com. jfans. sample, it will be changed to "com/jfans/sample"
Name =
Name. replaceall ("//.","////");

FS = new fileinputstream (new file (path + name + filetype ));
Baos
= New bytearrayoutputstream ();
Int CH = 0;
While (
(CH = FCM. Read ())! =-1 ){
Baos. Write (CH );

}
Data = baos. tobytearray ();
} Catch (ioexception
E ){
// System. Out. println ("exception E:" + E );
// Exception Conversion

Throw new classnotfoundexception ("class is not found:" + name, e );

} Finally {
Try {
If (FS! = NULL ){

FCM. Close ();}
If (baos! = NULL ){
Baos. Close ();}

} Catch (ioexception IOE ){
IOE. printstacktrace ();
}

}
Return data;
}
 
 
// Method for rewriting the custom Loader
Protected class
Findclass (string name) throws classnotfoundexception {
Byte [] DATA =
Loadclassdata (name );
Return defineclass (name, Data, 0,
Data. Length );
}

}

Test class:
Package com. jfans;

Public class myclassloadertest {

Public static void main (string [] ARGs ){

Myclassloader loader1 = new
Myclassloader ("loader1 ");
Loader1.setpath ("D:/MyApp/serverlib /");

Myclassloader
Loader2 = new
Myclassloader (loader1, "loader2 ");
Loader2.setpath ("D:/MyApp/clientlib /");

Myclassloader
Loader3 = new
Myclassloader (null, "loader3 ");
Loader3.setpath ("D:/MyApp/otherlib /");



Test (loader1 );
Test (loader2 );
Test (loader3 );

}
Private
Static void test (classloader ){
Try {
Class personclass =
Classloader. loadclass ("com. jfans. person ");
Object OBJ =
Personclass. newinstance ();
} Catch (classnotfoundexception e ){
//
Todo auto-generated Catch Block
E. printstacktrace ();
} Catch
(Instantiationexception e ){
// Todo auto-generated catch
Block
E. printstacktrace ();
} Catch (illegalaccessexception E)
{
// Todo auto-generated catch
Block
E. printstacktrace ();
}

}

}

// Person class
Package com. jfans;

Public class person {

Private string name;

Public Person (){
This. Name = "cuser"; // default
Value
System. Err. println ("person is load by:" +
This. getclass (). getclassloader (); // observe the printed result.
}
 
Public
Personx (string name ){
This. Name = Name;
}
Public String getname ()
{
Return name;
}

Public void setname (string name ){
This. Name = Name;
}
}

 

Test method: Put the person class under the directory (PATH) specified by loader1, loader2, and loader3 respectively. Perform tests by combining, deleting, and so on. I believe we can observe the loader to which the person is loaded, and under what circumstances will there be classnotfoundexception.
Before testing, read the code and remember the parent delegation mechanism.

The namespaces of different class loaders have the following relationships:
● Classes in the same namespace are mutually visible.
● The Sub-loader namespace contains the namespaces of all parent loaders. Therefore, the class loaded by the sub-loader can see the class loaded by the parent loader. For example, the class loaded by the system class loader can see the class loaded by the root class loader.

● The class loaded by the parent loader cannot see the class loaded by the sub-loader.
● If there is no direct or indirect parent-child relationship between the two loaders, their respective classes are invisible to each other.
Class A can see Class B, that is, the name of Class B can be referenced in the program code of Class. For example:
Class
A {
B = new B ();
}

Urlclassloader class
In the JDK java.net package, a powerful urlclassloader class is provided, which extends the classloader class. It not only loads classes from the local file system, but also downloads classes from the Internet. Java programs can directly use the urlclassloader class as a user-defined class loader. The urlclassloader class provides the following constructor methods:
URL (URL []
URLs) // The parent loader is the system class loader.
URL (URL [] URLs, classloader parent)
// The parent parameter specifies the parent loader.
The URLs parameter in the preceding constructor stores all URL paths. The urlclassloader loads classes from these paths.

Class uninstallation
After the sample class is loaded, connected, and initialized, its lifecycle begins. When the class object representing the sample class is no longer referenced, that is, it cannot be touched in a timely manner, the class object will end its lifecycle, and the data of the sample class in the method area will also be uninstalled, end the lifecycle of the sample class. It can be seen that when a class ends its lifecycle depends on when its class object ends its lifecycle. This is a big topic.

Classes loaded by the class loader that comes with the Java Virtual Machine will never be uninstalled during the life cycle of the virtual machine. As mentioned earlier, the class loaders of the Java Virtual Machine include the root class loaders, extended class loaders, and system class loaders. the Java Virtual Machine itself will always reference these classes to load empty or empty, these class loaders always reference the class objects of the classes they load, so these class objects are always accessible.

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.