ClassLoader Details of Dafa color _ ticket platform construction in super-detailed Java

Source: Internet
Author: User
Tags static class stub ticket

ClassLoader translation is the ClassLoader, the average Java developers actually use a few, but for some framework developers are very common. Understanding the loading mechanism of ClassLoader also helps us to write more efficient code. The specific role of ClassLoader is to load the class file into the JVM virtual machine, and the program will run correctly. However, when the JVM starts, it does not load all the class files at once, but instead dynamically loads them as needed. Think of the same, one-time loading so many jar package so many classes, that memory does not crash. The purpose of this article is also to learn classloader this loading mechanism.

Daihatsu Color _ Ticket Platform Construction
Address one: "hubawl.com" Fox PA Source Forum
Address two: "Bbscherry.com"

Note: The length of this article is long, but the content is simple, we do not panic, quiet and patiently read is

Knowledge of class files

We all know that in the Java program is running in the virtual machine, we usually write with a text editor or IDE program is a. java file, this is the most basic source code, but such files are not directly run. As we write a simple program Helloworld.java

public class helloworld{

public static void main(String[] args){    System.out.println("Hello world!");}

}

Write a picture description here
Then we need to compile the Java files on the command line

Javac Helloworld.java
Write a picture description here
You can see that the. class file is generated under the directory

We then execute the command from the command line:

Java HelloWorld
Write a picture description here

Above is the basic code example, is all the beginning of the Java language has been learned, here to re-come out to let everyone focus on the class file, class file is a byte code format file, Java virtual machines do not directly identify the. Java source files that we normally write, so we need to javac this command into a. class file. Also, if a program written in C or Python is correctly converted to a. class file, the Java Virtual machine is also recognized as running. For more information, please refer to this article.

After understanding the. class file, let's consider how the Java programs we normally write in Eclipse run, that is, how the various classes we write ourselves are loaded into the JVM (Java Virtual machine).

Do you remember the Java environment variables?

Beginners Java, the most afraid of is to download the JDK to configure the environment variables, the key is not understood at the time, so gingerly follow the book or the introduction of the network on the operation. And then the next time you make it, you forget it and you will forget it. At that time, the heart of the idea is very angry, thinking is-this thing is not human, why do you have to configure the environment variable it? Too do not take care of rookie and novice, many rookie is because the card in the environment variable configuration, suffered too much frustration.

Because I am programming under Windows, I only talk about the environment variables on the window platform, there are 3 main: Java_home, PATH, CLASSPATH.

Java_home

Refers to the location of your JDK installation, which is usually installed by default on the C drive, such as

C:\Program files\java\jdk1.8.0_91
PATH

After you include the program path in path, you can type its name directly in the command-line window, instead of typing its full path, such as the one I used in the above code to JAVAC and Java two commands.
of General

path=%java_home%\bin;%java_home%\jre\bin;%path%;
That is, add the bin directory of the JDK directory and the JRE directory to the original path path.

CLASSPATH

Classpath=.; %java_home%\lib;%java_home%\lib\tools.jar
One look is pointing to the jar package path.
It is important to note that the preceding.;,. Represents the current directory.

setting and viewing of environment variables

Settings can right click on My Computer, then click Properties, then click Advanced, and then click on the environment variable, specifically do not understand the self-lookup document.

Open a command-line window if you view it

Echo%java_home%

Echo%PATH%

Echo%classpath%
Ok, pull away, know the environment variables, especially classpath, we enter today's theme ClassLoader.

Java class loading process

The Java language system comes with a three class loader:

    • Bootstrap ClassLoader the topmost load class, the main load core class library,%jre_home%\lib under the Rt.jar, Resources.jar, Charsets.jar and class. It is also important to note that you can change the loading directory of the bootstrap ClassLoader by specifying the-xbootclasspath and path when you start the JVM. For example, java-xbootclasspath/a:path the specified file is appended to the default bootstrap path. We can open my computer and look in the directory above to see if these jar packages are present in this directory.
    • Extention ClassLoader extends the class loader, loading the jar package and class files in the directory%jre_home%\lib\ext directory. You can also load the directory specified by the-d java.ext.dirs option.
    • Appclass Loader is also known as Systemappclass to load all classes of the currently applied Classpath.

We have briefly introduced 3 ClassLoader. Describes the paths that they load. The two virtual machine parameter options,-xbootclasspath and-D java.ext.dirs, are also mentioned.

Load order?

We have seen the system's 3 ClassLoader, but we may not know which one to go first.
I can tell you the answer first.

    1. Bootstrap Classloder
    2. Extention ClassLoader
    3. Appclassloader

For a better understanding, we can view the source code.
Look at Sun.misc.Launcher, which is a Java Virtual Machine portal application.

Public class Launcher {
private static Launcher Launcher = new Launcher ();
private static String Bootclasspath =
System.getproperty ("Sun.boot.class.path");

public static Launcher getLauncher() {    return launcher;}private ClassLoader loader;public Launcher() {    // Create the extension class loader    ClassLoader extcl;    try {        extcl = ExtClassLoader.getExtClassLoader();    } catch (IOException e) {        throw new InternalError(            "Could not create extension class loader", e);    }    // Now create the class loader to use to launch the application    try {        loader = AppClassLoader.getAppClassLoader(extcl);    } catch (IOException e) {        throw new InternalError(            "Could not create application class loader", e);    }    //设置AppClassLoader为线程上下文类加载器,这个文章后面部分讲解    Thread.currentThread().setContextClassLoader(loader);}/* * Returns the class loader used to launch the main application. */public ClassLoader getClassLoader() {    return loader;}/* * The class loader used for loading installed extensions. */static class ExtClassLoader extends URLClassLoader {}

/**

    • The class loader used for loading from Java.class.path.
    • Runs in a restricted security context.
      */
      Static Class Appclassloader extends URLClassLoader {}
      The source code is streamlined and we can get the relevant information.
      1. Launcher initializes the Extclassloader and Appclassloader.
      2. Launcher did not see Bootstrapclassloader, but System.getproperty ("Sun.boot.class.path") got the string Bootclasspath, This should be the path of the Bootstrapclassloader loaded jar package.

We can test what Sun.boot.class.path is in the code first.

System.out.println (System.getproperty ("Sun.boot.class.path"));
The resulting results are:

C:\Program Files\java\jre1.8.0_91\lib\resources.jar;
C:\Program Files\java\jre1.8.0_91\lib\rt.jar;
C:\Program Files\java\jre1.8.0_91\lib\sunrsasign.jar;
C:\Program Files\java\jre1.8.0_91\lib\jsse.jar;
C:\Program Files\java\jre1.8.0_91\lib\jce.jar;
C:\Program Files\java\jre1.8.0_91\lib\charsets.jar;
C:\Program Files\java\jre1.8.0_91\lib\jfr.jar;
C:\Program files\java\jre1.8.0_91\classes
As you can see, these are all jar packages or class files in the JRE directory.

Extclassloader Source

If you have enough curiosity, you should be interested in its source code.

/*

  • The class loader used for loading installed extensions.
    */
    Static Class Extclassloader extends URLClassLoader {

    static {classloader.registerasparallelcapable ();} /** * Create an Extclassloader. The Extclassloader is created * within a context that limits which files it can read */public static Extclassloader Getext    ClassLoader () throws ioexception{final file[] dirs = Getextdirs ();  try {//Prior implementations of this doprivileged () block supplied//AA synthesized ACC via a call to the        Private method//Extclassloader.getcontext (). Return accesscontroller.doprivileged (New privilegedexceptionaction<extclassloader> () {PU                    Blic Extclassloader Run () throws IOException {int len = dirs.length;                    for (int i = 0; i < len; i++) {metaindex.registerdirectory (dirs[i]);                } return new Extclassloader (dirs);    }            });   } catch (Java.security.PrivilegedActionException e) {throw (IOException) e.getexception (); }}private Static file[] Getextdirs () {String s = system.getproperty ("Java.ext.dirs");    File[] dirs;        if (s! = null) {StringTokenizer st = new StringTokenizer (s, file.pathseparator);        int count = St.counttokens ();        dirs = new File[count];        for (int i = 0; i < count; i++) {dirs[i] = new File (St.nexttoken ());    }} else {dirs = new file[0]; } return dirs;}

......
}
As we said earlier, you can specify the-D java.ext.dirs parameter to add and change the Extclassloader load path. Here we can write the test code.

System.out.println (System.getproperty ("Java.ext.dirs"));
The results are as follows:

C:\Program Files\java\jre1.8.0_91\lib\ext; C:\Windows\Sun\Java\lib\ext
Appclassloader Source

/**

    • The class loader used for loading from Java.class.path.
    • Runs in a restricted security context.
      */
      Static Class Appclassloader extends URLClassLoader {

      public static ClassLoader getAppClassLoader(final ClassLoader extcl)    throws IOException{    final String s = System.getProperty("java.class.path");    final File[] path = (s == null) ? new File[0] : getClassPath(s);    return AccessController.doPrivileged(        new PrivilegedAction<AppClassLoader>() {            public AppClassLoader run() {            URL[] urls =                (s == null) ? new URL[0] : pathToURLs(path);            return new AppClassLoader(urls, extcl);        }    });}......

      }
      You can see that appclassloader is loading the path under Java.class.path. We also print its value.

System.out.println (System.getproperty ("Java.class.path"));
Results:

D:\workspace\ClassLoaderDemo\bin
This path is actually the current Java project directory bin, which contains the compiled generated class file.

Well, since we have learned that Bootstrapclassloader, Extclassloader, Appclassloader are actually looking at the corresponding environment properties Sun.boot.class.path, Java.ext.dirs and Java.class.path to load the resource file.

Next we explore the order in which they are loaded, and we first build a Java project with Eclipse.
Write a picture description here
Then create a Test.java file.

public class test{}
Then, write a Classloadertest.java file.

public class Classloadertest {

public static void main(String[] args) {    // TODO Auto-generated method stub    ClassLoader cl = Test.class.getClassLoader();    System.out.println("ClassLoader is:"+cl.toString());}

}
We get the class loader for the Test.class file and print it out. The result is:

ClassLoader Is:[email protected]
That is, the Ming Test.class file is loaded by Appclassloader.

This test class is written by ourselves, so who is the Int.class or string.class loading?
We can try in the code

public class Classloadertest {

public static void main(String[] args) {    // TODO Auto-generated method stub    ClassLoader cl = Test.class.getClassLoader();    System.out.println("ClassLoader is:"+cl.toString());    cl = int.class.getClassLoader();    System.out.println("ClassLoader is:"+cl.toString());}

}
Run it, but it's an error.

ClassLoader Is:[email protected]
Exception in thread "main" java.lang.NullPointerException
At Classloadertest.main (classloadertest.java:15)
The hint is a null pointer, which means that the base class like Int.class does not have a classloader loaded?

Of course not!
The Int.class is loaded by the bootstrap ClassLoader. To figure this out, we need to know a premise first.

Each classloader has a parent loader

Each classloader has a parent loader, such as loading test.class is done by Appclassloader, then Appclassloader also has a parent loader, how to get it? Very simple, through the GetParent method. For example, the code can be written like this:

ClassLoader cl = Test.class.getClassLoader ();

System.out.println ("ClassLoader is:" +cl.tostring ());
System.out.println ("Classloader\ ' s parent is:" +cl.getparent (). toString ());
The results of the operation are as follows:

ClassLoader Is:[email protected]
ClassLoader ' s parent is:[email protected]
In this note, Appclassloader's parent loader is extclassloader. So who is Extclassloader's parent loader?

System.out.println ("ClassLoader is:" +cl.tostring ());
System.out.println ("Classloader\ ' s parent is:" +cl.getparent (). toString ());
System.out.println ("Classloader\ 's grand father is:" +cl.getparent (). GetParent (). toString ());
Run if:

ClassLoader Is:[email protected]
Exception in thread "main" ClassLoader ' s parent is:sun.misc.launcher$extclassload[email protected]
Java.lang.NullPointerException
At Classloadertest.main (classloadertest.java:13)
Another null pointer exception, which indicates that Extclassloader also has no parent loader. So why does the title and every loader have a parent loader? Isn't that contradictory? To explain this, we also need to look at the following basic premise.

Parent loader is not a parent class

We have previously pasted the code for Extclassloader and Appclassloader.

Static Class Extclassloader extends URLClassLoader {}
Static Class Appclassloader extends URLClassLoader {}
You can see that Extclassloader and Appclassloader also inherit from URLClassLoader, but in the above section of the code, why Appclassloader is called GetParent () Will the code get an instance of Extclassloader? First of all, from URLClassLoader, what is this class?
First the inheritance diagram of a class
Write a picture description here

URLClassLoader's source code did not find the GetParent () method. This method is in Classloader.java.

Public abstract class ClassLoader {

The parent class loader for delegation
NOTE:VM hardcoded The offset of this field, thus all new fields
Must is added after it.
Private final ClassLoader parent;
The class loader for the system
@GuardedBy ("Classloader.class")
private static ClassLoader SCL;

Private ClassLoader (Void unused, ClassLoader parent) {
This.parent = parent;
...
}
Protected ClassLoader (ClassLoader parent) {
This (Checkcreateclassloader (), parent);
}
Protected ClassLoader () {
This (Checkcreateclassloader (), Getsystemclassloader ());
}
Public final ClassLoader getParent () {
if (parent = = NULL)
return null;
return parent;
}
public static ClassLoader Getsystemclassloader () {
Initsystemclassloader ();
if (SCL = = null) {
return null;
}
return SCL;
}

Private static synchronized void Initsystemclassloader () {
if (!sclset) {
if (SCL! = null)
throw new Illegalst Ateexception ("recursive invocation");
Sun.misc.Launcher L = sun.misc.Launcher.getLauncher ();
if (l! = null) {
Throwable oops = null;
Get ClassLoader
SCL = L.getclassloader () by launcher;
try {
SCL = accesscontroller.doprivileged (
New Systemclassloaderaction (SCL));
} catch ( Privilegedactionexception PAE) {
Oops = Pae.getcause ();
if (oops instanceof invocationtargetexception) {
oops = Oops.getcause ();
}
}
if (oops! = null) {
if (oops instanceof error) {
Throw (error) oops;
} else {
//wrap the Exceptionthrow new Error (oops);
}
}
}
Sclset = true;
}
}
}
We can see that getparent () actually returns the assignment of a ClassLoader object parent,parent is in the constructor of the ClassLoader object, which has two conditions:

    1. When you create a classloader by an external class, you specify a classloader as the parent directly.
    2. Generated by the Getsystemclassloader () method, which is obtained by sun.misc.Laucher through getClassLoader (), which is appclassloader. Frankly speaking, if a classloader is created without the parent specified, its parent defaults to Appclassloader.

Our main research is the source of the parent of Extclassloader and Appclassloader, just as they relate to the launcher class, and we have pasted part of the launcher code above.

public class Launcher {
private static URLStreamHandlerFactory factory = new Factory ();
private static Launcher Launcher = new Launcher ();
private static String Bootclasspath =
System.getproperty ("Sun.boot.class.path");

public static Launcher getLauncher() {    return launcher;}private ClassLoader loader;public Launcher() {    // Create the extension class loader    ClassLoader extcl;    try {        extcl = ExtClassLoader.getExtClassLoader();    } catch (IOException e) {        throw new InternalError(            "Could not create extension class loader", e);    }    // Now create the class loader to use to launch the application    try {    //将ExtClassLoader对象实例传递进去        loader = AppClassLoader.getAppClassLoader(extcl);    } catch (IOException e) {        throw new InternalError(            "Could not create application class loader", e);    }

Public ClassLoader getClassLoader () {
return loader;
}
Static Class Extclassloader extends URLClassLoader {

    /** * Create an Extclassloader. The Extclassloader is created * within a context that limits which files it can read */public static EXTCLASSL        Oader Getextclassloader () throws IOException {final file[] dirs = Getextdirs (); try {//Prior implementations of this doprivileged () block supplied//AA synthesized ACC via a CAL            L to the Private method//Extclassloader.getcontext ().                    Return accesscontroller.doprivileged (New privilegedexceptionaction<extclassloader> () {                        Public Extclassloader Run () throws IOException {//extclassloader is created here                    return new Extclassloader (dirs);        }                });        } catch (Java.security.PrivilegedActionException e) {throw (IOException) e.getexception ();     }}/* * Creates a new extclassloader for the specified directories. */Public ExtclasslOader (file[] dirs) throws IOException {super (Getexturls (dirs), NULL, factory); }    }

}
What we need to be aware of

ClassLoader EXTCL;

EXTCL = Extclassloader.getextclassloader ();

Loader = Appclassloader.getappclassloader (EXTCL);
The code has explained the problem Appclassloader's parent is a Extclassloader instance.

Extclassloader did not directly find the assignment to the parent. It calls its parent class, the constructor of Urlclassloder, and passes 3 arguments.

ClassLoader Details of Dafa color _ ticket platform construction in super-detailed Java

Related Article

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.