ClassLoader Detailed and use (good writing)

Source: Internet
Author: User
Tags xml parser

ClassLoader primarily serves the request of a class, when a class is required by the JVM, it requires the class according to the name, and then returns the class object of ClassLoader by ClassLoader. 1.1 Several related concepts ClassLoader all resources (Class, file, byte stream from the network, etc.) that are responsible for loading the system through ClassLoader to load the resource into the JVM
Each class has a reference that points to its own classloader. Class.getclassloader ()
The ClassLoader of an array is the classloader of its elements, and if the base data type, the array is not ClassLoader
1.2 Main methods and working process Java1.1 and previous versions, ClassLoader main methods:
Class loadclass (String name, Boolean resolve); Classloader.loadclass () is the entry point of ClassLoader
The DefineClass method is the main trick of ClassLoader. The method accepts an array of primitive bytes and converts it into a Class object. The original array contains data that is loaded from the file system or network.
The Findsystemclass method loads files from the local file system. It looks for the class file in the local file system and, if it exists, uses defineclass to convert the raw bytes to a class object to convert the file into classes. This is the default mechanism for the JVM to load classes properly when running Java applications.
Resolveclass can be loaded into classes without complete (without parsing), or they can be loaded completely (with parsing). When writing our own loadclass, you can call Resolveclass, depending on the value of the Resolve parameter of LoadClass
Findloadedclass acts as a cache: When a request LoadClass loads a class, it calls the method to see if the ClassLoader has been loaded into the class, which avoids the hassle of reloading the existing class. The method should be called first
The general Load method process is as follows:

Call Findloadedclass to see if there is a loaded class.
If not, then take some special magical way to get the raw bytes. (via IO From file system, byte stream from network, etc.)
If there are already primitive bytes, call DefineClass to convert them to Class objects.
If there are no raw bytes, then call Findsystemclass to see if the class is fetched from the local file system.
If the resolve parameter is true, then call Resolveclass to parse the Class object.
If there are no classes, return to ClassNotFoundException.
Otherwise, the class is returned to the calling program.
1.3 Delegate model since JDK1.2, ClassLoader has made improvements, using the delegation model, all the system classloader form a tree, ClassLoader in the class library when the first to find the parent, the parent can not find to find.
The JVM generates three Classloader,bootstrap ClassLoader, Extension ClassLoader, and app ClassLoader at run time. Where Bootstrap ClassLoader is written in C + + and is not visible in Java, it is null. It is used to load the core class library, that is, the class library under the Lib, Extension ClassLoader loading Lib/ext class library, the app ClassLoader loading classpath class library, the relationship between the three is: App The parent of ClassLoader is extension ClassLoader, while the parent of extension ClassLoader is bootstrap ClassLoader. Loading a class, first bootstrap to find, can not find again by extension ClassLoader Search, the end is the app ClassLoader.

An important reason to design classloader as a delegate model is for security reasons, such as in applets, if you write a java.lang.String class and are destructive. Without such a delegation mechanism, this destructive string is loaded onto the user's machine, causing the user's security to be compromised. However, this is not the case with this delegation mechanism. Because the Java.lang.String class is loaded, the system will eventually be loaded by bootstrap, a destructive string that never has a chance to load.

The delegate model also poses some problems, which can be confusing in some cases, as shown in the Tomcat ClassLoader structure diagram:

Bootstrap
|
System
|
Common
/
Catalina GKFX
/
Webapp1 Webapp2 ...

Classes loaded by the Common class loader must not directly access the classes loaded by the WEB application (by name). The only way to associate these classes is by using the interfaces that are visible through the two class sets. In this example, Javax.servlet.Servlet is included in the Java servlet implementation.
If a class library such as Lib or Lib/ext has the same class as the application, then the class in the application cannot be loaded. There is usually a problem when a new version of the JDK has a class library move, such as when we first used our own XML parser. In jdk1.4, the XML parser becomes the standard class library, and the load priority is higher than our own XML parser, and our own XML parser can never be found, which could cause our app to fail to run.

The same class, different classloader, will cause classcastexception exceptions

ClassLoader in 1.4 threads each running thread has a member Contextclassloader that is used to dynamically load other classes at run time, using Method Thread.CurrentThread (). Setcontextclassloader (...); Change the contextclassloader of the current thread to change the behavior of its loaded class, or you can obtain the ClassLoader of the current thread by means of Thread.CurrentThread (). Getcontextclassloader ().
In fact, in the Java application All programs are running in the thread, if the program is not manually set ClassLoader, for the general Java class The following two ways to obtain the ClassLoader is usually the same

This.getClass.getClassLoader ();
Thread.CurrentThread (). Getcontextclassloader ();
The ClassLoader obtained by the method is static, indicating who is the loader of the class, and the ClassLoader that the method two obtains is dynamic, who executes (a thread), which is the classloader of the executor. For singleton mode classes, static classes, etc., once loaded, this instance is called by many programs (threads), and for these classes, the ClassLoader of the loaded classloader and execution threads are usually different.

1.5 WEB application ClassLoader back to the example above, in Tomcat, WebApp's ClassLoader works a little differently, it first tries to load the class itself (in contextpath/web-inf/... If it fails to load, then request the parent ClassLoader to complete.
This can be done by:

For the web App thread, its contextclassloader is WebappClassLoader
For the Tomcat server thread, its contextclassloader is Catalinaclassloader
1.6 Several methods of obtaining classloader can be classloader by the following 3 ways
This.getClass.getClassLoader (); Use the ClassLoader of the current class
Thread.CurrentThread (). Getcontextclassloader (); Use the ClassLoader of the current thread
Classloader.getsystemclassloader (); Use the system ClassLoader, which is the ClassLoader used by the entry point of the system. (Note that the system ClassLoader is not the same as the root ClassLoader.) The system ClassLoader under the JVM is typically app ClassLoader)
1.7 Types of extension applications users can customize their own classloader to achieve some of the following applications
Security. Class goes through ClassLoader before entering the JVM, so you can check for the correct digital signature here.
Encryption. Java bytecode is easy to decompile, by customizing the ClassLoader so that the bytecode encryption to prevent others to download after the anti-compilation, where the ClassLoader equivalent of a dynamic decoder
Archive. You may want to save network resources, do some special archiving of your own code, and then use the customized ClassLoader to solve the file
Self-expanding programs. Compile the Java application into a single executable class file that contains compressed and encrypted class file data with a fixed classloader that is fully self-extracting in memory when the program is running, without first installing
Dynamically generated. You can generate classes that apply other classes that have not yet been generated, create the entire class in real time, and introduce the JVM at any time
2.0 Resources Loaded in
All resources are loaded into the JVM via ClassLoader, so you can certainly use ClassLoader when loading resources, but you can also load them in some other way for different resources, for example, the class can be directly new, the file can be directly IO, etc. 2.1 Several methods of loading classes assume that Class A and class b,a are required to instantiate B in the method Amethod, there are 3 possible methods. For loading classes, the user needs to know the full name of Class B (including the package name, such as "com.rain.b")
1. Using the Class static method Class.forName

Class cls = Class.forName ("com.rain.b");
b b = (b) cls.newinstance ();

2. Using ClassLoader
/* Step 1. Get ClassLoader */
ClassLoader cl; How to get ClassLoader reference 1.6

/* Step 2. Load the class */
Class cls = Cl.loadclass ("com.rain.b"); Use the first step to get the ClassLoader to load B

/* Step 3. new instance */
b b = (b) cls.newinstance (); A class with B gets an instance of B

3. Direct NEW
b b = new B ();

2.2 File loading (e.g. configuration file, etc.) suppose you want to read the folder in the Com.rain.a class/com/rain/config File Sys.properties, the read file can be either an absolute path or a relative path, the absolute path is simple, starting with the disk number under Windows, starting with "/" under Unix
For a relative path, its relative value is relative to ClassLoader, because ClassLoader is a tree, so the relative path and any classloader on the ClassLoader tree can be found in relative comparison, then the file can be found, of course, Read files also use the delegate model

1. Direct IO

/**
* Assuming the current position is "c:/test", run A "Java Com.rain.a" by executing the following command
* 1. The absolute path can be used in the program, the absolute path under Windows begins with the disk number, and Unix starts with "/".
* 2. You can also use a relative path with no "/" in front of the relative path
* Because we execute the program under the "C:/test" directory, the program entry point is "c:/test" and the relative path is
* is "com/rain/config/sys.properties"
* (in the example, the ClassLoader of the current program is the app Classloader,system ClassLoader = current
* The ClassLoader of the program, the entry point is "C:/test")
* For ClassLoader tree, if the file is under JDK Lib, if the file is under the JDK Lib/ext, if the file is in the environment variable,
* Can be found by the relative path "Sys.properties", lib files are first found
*/
File F = new file ("C:/test/com/rain/config/sys.properties"); Using absolute paths
File F = new file ("Com/rain/config/sys.properties"); Using relative paths
InputStream is = new FileInputStream (f);

If it is a configuration file, the content can be read into the properties through Java.util.Properties.load (IS), properties by default, is the encoding is iso-8859-1, if the configuration file is non-English, garbled problems may occur.
2. Using ClassLoader

/**
* Because there are 3 ways to get ClassLoader, the following 3 ways should be read file
* The path used is relative to the point relative to the ClassLoader, where only relative paths are used
*/
InputStream is = null;
is = This.getclass (). getClassLoader (). getResourceAsStream (
"Com/rain/config/sys.properties"); Method 1
is = Thread.CurrentThread (). Getcontextclassloader (). getResourceAsStream (
"Com/rain/config/sys.properties"); Method 2
is = Classloader.getsystemresourceasstream ("com/rain/config/sys.properties"); Method 3

In the case of a configuration file, the content can be read into the Properties via Java.util.Properties.load (IS), where the coding problem is noted.
3. Using ResourceBundle

ResourceBundle bundle = Resourcebundle.getboundle ("Com.rain.config.sys");

This usage is usually used to load the user's profile, please refer to other documents for more detailed usage of Resourcebunlde
Summary: There are 3 ways to load files

1. Absolute path---> IO
2. Relative Path---> IO
---> ClassLoader
3. resource Files---> ResourceBundle

2.3 How to load resources in a Web application it is also possible to use ClassLoader to load resources in Web applications, but it is more common to use ServletContext, the following is the web directory structure
Contextroot
|-JSP, HTML, image and many other files
|-[Web-inf]
|-Web
|-[lib] the jar file used by the Web
|-[Classes] class file

The user program is usually in the classes directory, if you want to read the classes directory files, you can use ClassLoader, if you want to read other files, generally use Servletcontext.getresource ()
If you use the Servletcontext.getresource (path) method, the path must begin with "/", the path is interpreted as relative to the Contextroot path, and the method to load the file here differs from ClassLoader, for example "/web-inf/ Web. xml ","/download/webexagent.rar "

ClassLoader Detailed and use (good writing)

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.