Classloader ClassLoader,Thread.currentThread().setContextClassLoader,tomcat的ClassLoader

ClassLoader,Thread.currentThread().setContextClassLoader,tomcat的ClassLoader

21:41 2014-05-07   Loull   reading ( 6776) Comments ( 0)   edit  collections

In fact, Java applications run all programs in the thread, if not manually set too ClassLoader, in the program are usually the same for the average ClassLoader java class follows two methods of 

this.getClass.getClassLoader();  
Thread.currentThread().getContextClassLoader();  

A method of Classloader get is static, the class who show who is loaded;

Method two get Classloader is dynamic, who perform (a thread) is Classloader the performer. For singleton class, static, etc., after loading time, this instance is a lot of programs (threads) calling for these classes, loaded Classloader Classloader and execution threads are usually different.

 

A thread context class loader

  Class loader thread context (context class loader) is introduced from the beginning JDK 1.2. Class  java.lang.Threadmethod  getContextClassLoader()and setContextClassLoader(ClassLoader cl)is used to get and set thread's context class loader. If no By  setContextClassLoader(ClassLoader cl)setting method, then the thread will inherit the parent thread context class loader's. Initial thread running Java application context class loader is the system class loader (appClassLoader). Code running in the thread can load classes and resources through this class loader.

  Proxy mode previously mentioned class loader does not solve all the problems encountered in the development of Java application class loader. Java provides many service provider interface (Service Provider Interface, SPI), allow third parties to provide implementations for these interfaces. Common SPI has JDBC, JCE, JNDI, JAXP and JBI and so on. The SPI interface is provided by the core Java libraries, as JAXP SPI interface definitions are contained in  javax.xml.parsersthe package. The SPI code is likely to be implemented as a Java application depends jar package is included in, a path can be found by the class (the CLASSPATH), such as the SPI achieve the JAXP  the Apache Xerces jar package contains. SPI interfaces often need to load the code in a specific category. As in JAXP  javax.xml.parsers.DocumentBuilderFactoryclass  newInstance()method is used to generate a new DocumentBuilderFactoryinstance. True instance of the class inherits from here  javax.xml.parsers.DocumentBuilderFactory, by the implementation of the SPI is provided. As Apache Xerces, the implementation class is  org.apache.xerces.jaxp.DocumentBuilderFactoryImpl. The problem is, the SPI interface is a core part of the Java library, by the bootstrap class loader to load; SPI Java class implemented typically by the system class loader to load. Bootstrap class loader can not find the SPI implementation class, because it only loads the core Java libraries. It can not be the agent to the system class loader, because it is the ancestor of the system class loader class loader. In other words, proxy mode class loader can not solve this problem.

  Thread context class loader just to solve this problem. If you do not do any settings, Java application thread context class loader is the system default context class loader. Use thread context class loader code SPI interface, the load can be successfully implemented to the SPI class. Thread context class loader will be used in achieving many of SPI.

JNDI, JDBC demands are:

  In order to allow access to these applications jar package implementation class, i.e. with appClassLoarder to load the implementation class. Can get the current thread with getContextClassLoader ClassLoader (ie appClassLoarder), then to load the implementation class, you can let the application access to .

tomcat demands:

  A little bit different with the above, the container does not want it between the following webapps able to visit each other, so you can not use appClassLoarder to load. Therefore, a new tomcat sharedClassLoader (its parent is commonClassLoader, commonClassLoader the parent is appClassLoarder, by default, sharedClassLoader and commonClassLoader UrlClassLoader example is the same), which is used ClassLoader catalina container. For each webapp, for a new WebappClassLoader, webapp following classes for loading, so that between the webapp can not access each other. tomcat does not fully comply with the ClassLoader parent delegation, first with webappClassLoader to load a class, if not, then to the parent. For ClassLoader java core library, not the tomcat load range.

  Look Bootstrap class init method of tomcat:

Copy the code
void the init public () throws Exception { 

        initClassLoaders (); 

        . Thread.currentThread () setContextClassLoader (catalinaLoader); // do not know after this line is set up, what's the use of the back? ? ? 

        SecurityClassLoad.securityClassLoad (catalinaLoader); 

        // class and the Load Our Startup Process ITS Call () Method / * instance * / reflection Catalina instantiated class 
        <?> = Class startupClass 
            catalinaLoader.loadClass 
            ( "org.apache.catalina.startup. catalina "); 
        Object startupInstance = startupClass.newInstance (); // the Set at The Shared Extensions class Loader 
        IF (log.isDebugEnabled ()) 
            log.debug (" Setting the Startup class the Properties ");
        String methodName =" setParentClassLoader "; 
        <?> class paramTypes [] = new new class [1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);

        catalinaDaemon = startupInstance;

    }
Copy the code

 

  Since catalina Bootstrap classes and classes which are released in different packages, the operation of the Bootstrap catalina instance must complete reflection.

  catalina class instances (i.e. startupClass) generated by the reflector, it is ClassLoader catalinaLoader. The method call is then reflected setParentClassLoader disposed inside catalina class instance variable is parentClassLoader sharedClassLoader, meaning that a lower container webappClassLoader webapp as the parent, and the parent ClassLoader class is not provided catalina sharedClassLoader.

  Now tomcat init method of Bootstrap class inside Thread.currentThread () setContextClassLoader (catalinaLoader);. This line is still very confused. Because, in the class catalina which can be used getClass (). GetClassLoader () Gets catalinaClassLoader, need not (). GetContextClassLoader () method to obtain from Thread.currentThread. Is ClassLoader in order to allow the child thread is catalinaClassLoader, rather than appClassLoarder? ?

 

Second, the class loader and the container Web

  For running Web applications in Java EE ™ container, the class loader implementation of general Java application is different. Different implementations of Web container will be different. In Apache Tomcat, each has a corresponding Web application class loader instance. This class loader also use proxy mode, the difference is that it is the first attempt to load a class, if you can not find another proxy to the parent class loader. This general class loader order is reversed. This is the recommended practice of Java Servlet specification, which aims to make Web application priority class higher than their own class Web container provides. An exception to this pattern is the agent: Java core class libraries are not within the scope of the find. This is the type of Java core libraries in order to ensure safety.

  In most cases, Web application developers need to consider associated with the class loader details. Here are a few simple principles:

  • Each Web application own Java class files and libraries used jar package, respectively, on  WEB-INF/classesand  WEB-INF/libdirectory.
  • More shared Java class files and jar package applications, Web containers were placed in the following directory specified by the share of all Web applications.
  • When an error class not found appears, check the current class of the class loader and the current thread's context class loader is correct.

 

Third, the relationship ContextClassLoader and other ClassLoader 

  We can get through this context classloader getContextClassLoader method, you can use it to load the Class we need. The default is the system classloader.

  bootstrap classloader ------- corresponding to the jvm dll write a c ++ class
  Extenson ClassLoader --------- class corresponding to the internal ExtClassLoader
  the System ClassLoader --------- inner classes corresponding to the AppClassLoader
  the Custom ClassLoader ---------- correspond to any subclass of URLClassLoader (you can also inherit SecureClassLoader or more nb little direct successor ClassLoader, so you also existence of God and the XD)

  above four classloder from top to bottom order, followed by the next parent

  to this first concept

  second concept is related classloader several classes of

           the abstract class ClassLoader
                  |
            the SecureClassLoader
                   |
            URLClassloader
             | |                
 Sun ExtClassLoader sun of the AppClassLoader
  Is the class inheritance relationship between the above, with the first concept of parent say are two different things love, need to be careful.

  The third concept is the Thread of ContextClassLoader
  fact can be seen from the name of Context, this is only a temporary storage space to store any classloader reference, nothing to do with the classloader hierarchy.

 

Four, Context ClassLoader Detailed

  Typically, a total of four kinds of class loader, i.e. the boot class loader, the EXT class loader, App class loader and a custom class loader. Class case left between them as shown in FIG., They all have different loading rules, and carried out by upwardly proxy. The article mentioned Context Class Loader is not a new loader type, but an abstract argument, its specific form: Call Thread.getCurrentThread () getContextClassLoader () that ClassLoader returned. It JVM default class and custom class loader What is the relationship between it loaded? Here an experiment to see through it.

 

 

 

3 practical exercise

(1) a step

  FIG performed on such an experiment: First called Class (1) class start MainThread (in fact, the class which has the main function of it meaning), back pay attention to the name of the class indicated in its path (i.e. ClassPath), and then tested on the inside, it is found that the current load and the current thread (MainThread) of ContextClassLoader are AppClassLoader. Then Class (1) start a new thread Class (2). Where Class (2) is a subclass of Thread, a thread of execution Class (2) I call code Thread-0.

(2) Step two

  The figure can be seen that Class (2) and the loader are equally ContextClassLoader AppClassLoader. Then I created in Class (2) in a new URLCLassLoader, and use this to load another ClassLoader and Class (1) Class Class (3) not in the same ClassPath under. At this point we can see the changes: the loaded Class (3) of the loader is URLClassLoader, and ContextClassLoader also still AppClassLoader.

(2) Step Three

  Finally, we (3) start a thread in the Class class Class (4), found that Class (4) is loaded by the URLClassLoader, but this time ContextClassLoader still AppClassLoader.

    Throughout the process, the loading of class ClassLoader changed, since the thread class Class (4) is a Class (3) starts, so that it loads the class loader becomes URLClassLoader. At the same time, all the threads ContextClassLoader inherit the generation of the thread ContextClassLoader - AppClassLoader.

 

  Code green box if we performed at the end of the second step: setContextClassLoader (), the result becomes the following way:

 

  We can clearly see that because Thread-0 is set to ContextClassLoader became URLClassLoader, and Thread-1 is generated inside the Thread-0, so it inherits its ContextClassLoader, became URLClassLoader.

 

Postscript 3

  Test listed here may not necessarily comprehensive, but I think enough to explain the problem, should be able to explain the difference ContextClassLoader other class loader is located. Discuss but there are other differences there may ContextClassLoader, there is hope that the experience of friends.

 

  . Thread.currentThread () getContextClassLoader () meaning:

  Father Classloader can use the current thread Thread.currentthread (). GetContextLoader specified classloader loaded class (). Can not be used to subvert the parent ClassLoader or other sub Classloader Classloader no direct parent-child relationship in this case loaded classes. This is the Context Class Loader significance.

 

五、Current ClassLoader

  The current class belongs ClassLoader, between the virtual machine referenced in the class, the default is to use this ClassLoader. In addition, when you use Class.forName (), Class.getResource () when these ClassLoader methods without parameters, the current class also uses the default ClassLoader. You can () method to obtain by XX.class.GetClassLoader.

 

Reference

On Context Class Loader

On ContextClassLoader

https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

http://blog.sina.com.cn/s/blog_605f5b4f01010i48.html

 http://my.oschina.net/u/571166/blog/212903

In fact, Java applications run all programs in the thread, if not manually set too ClassLoader, in the program are usually the same for the average ClassLoader java class follows two methods of 

this.getClass.getClassLoader();  
Thread.currentThread().getContextClassLoader();  

A method of Classloader get is static, the class who show who is loaded;

Method two get Classloader is dynamic, who perform (a thread) is Classloader the performer. For singleton class, static, etc., after loading time, this instance is a lot of programs (threads) calling for these classes, loaded Classloader Classloader and execution threads are usually different.

 

A thread context class loader

  Class loader thread context (context class loader) is introduced from the beginning JDK 1.2. Class  java.lang.Threadmethod  getContextClassLoader()and setContextClassLoader(ClassLoader cl)is used to get and set thread's context class loader. If no By  setContextClassLoader(ClassLoader cl)setting method, then the thread will inherit the parent thread context class loader's. Initial thread running Java application context class loader is the system class loader (appClassLoader). Code running in the thread can load classes and resources through this class loader.

  Proxy mode previously mentioned class loader does not solve all the problems encountered in the development of Java application class loader. Java provides many service provider interface (Service Provider Interface, SPI), allow third parties to provide implementations for these interfaces. Common SPI has JDBC, JCE, JNDI, JAXP and JBI and so on. The SPI interface is provided by the core Java libraries, as JAXP SPI interface definitions are contained in  javax.xml.parsersthe package. The SPI code is likely to be implemented as a Java application depends jar package is included in, a path can be found by the class (the CLASSPATH), such as the SPI achieve the JAXP  the Apache Xerces jar package contains. SPI interfaces often need to load the code in a specific category. As in JAXP  javax.xml.parsers.DocumentBuilderFactoryclass  newInstance()method is used to generate a new DocumentBuilderFactoryinstance. True instance of the class inherits from here  javax.xml.parsers.DocumentBuilderFactory, by the implementation of the SPI is provided. As Apache Xerces, the implementation class is  org.apache.xerces.jaxp.DocumentBuilderFactoryImpl. The problem is, the SPI interface is a core part of the Java library, by the bootstrap class loader to load; SPI Java class implemented typically by the system class loader to load. Bootstrap class loader can not find the SPI implementation class, because it only loads the core Java libraries. It can not be the agent to the system class loader, because it is the ancestor of the system class loader class loader. In other words, proxy mode class loader can not solve this problem.

  Thread context class loader just to solve this problem. If you do not do any settings, Java application thread context class loader is the system default context class loader. Use thread context class loader code SPI interface, the load can be successfully implemented to the SPI class. Thread context class loader will be used in achieving many of SPI.

JNDI, JDBC demands are:

  In order to allow access to these applications jar package implementation class, i.e. with appClassLoarder to load the implementation class. Can get the current thread with getContextClassLoader ClassLoader (ie appClassLoarder), then to load the implementation class, you can let the application access to .

tomcat demands:

  A little bit different with the above, the container does not want it between the following webapps able to visit each other, so you can not use appClassLoarder to load. Therefore, a new tomcat sharedClassLoader (its parent is commonClassLoader, commonClassLoader the parent is appClassLoarder, by default, sharedClassLoader and commonClassLoader UrlClassLoader example is the same), which is used ClassLoader catalina container. For each webapp, for a new WebappClassLoader, webapp following classes for loading, so that between the webapp can not access each other. tomcat does not fully comply with the ClassLoader parent delegation, first with webappClassLoader to load a class, if not, then to the parent. For ClassLoader java core library, not the tomcat load range.

  Look Bootstrap class init method of tomcat:

Copy the code
void the init public () throws Exception { 

        initClassLoaders (); 

        . Thread.currentThread () setContextClassLoader (catalinaLoader); // do not know after this line is set up, what's the use of the back? ? ? 

        SecurityClassLoad.securityClassLoad (catalinaLoader); 

        // class and the Load Our Startup Process ITS Call () Method / * instance * / reflection Catalina instantiated class 
        <?> = Class startupClass 
            catalinaLoader.loadClass 
            ( "org.apache.catalina.startup. catalina "); 
        Object startupInstance = startupClass.newInstance (); // the Set at The Shared Extensions class Loader 
        IF (log.isDebugEnabled ()) 
            log.debug (" Setting the Startup class the Properties "); 
        String methodName =" setParentClassLoader "; 
        <?> class paramTypes [] = new new class [1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);

        catalinaDaemon = startupInstance;

    }
Copy the code

 

  Since catalina Bootstrap classes and classes which are released in different packages, the operation of the Bootstrap catalina instance must complete reflection.

  catalina class instances (i.e. startupClass) generated by the reflector, it is ClassLoader catalinaLoader. The method call is then reflected setParentClassLoader disposed inside catalina class instance variable is parentClassLoader sharedClassLoader, meaning that a lower container webappClassLoader webapp as the parent, and the parent ClassLoader class is not provided catalina sharedClassLoader.

  Now tomcat init method of Bootstrap class inside Thread.currentThread () setContextClassLoader (catalinaLoader);. This line is still very confused. Because, in the class catalina which can be used getClass (). GetClassLoader () Gets catalinaClassLoader, need not (). GetContextClassLoader () method to obtain from Thread.currentThread. Is ClassLoader in order to allow the child thread is catalinaClassLoader, rather than appClassLoarder? ?

 

Second, the class loader and the container Web

  For running Web applications in Java EE ™ container, the class loader implementation of general Java application is different. Different implementations of Web container will be different. In Apache Tomcat, each has a corresponding Web application class loader instance. This class loader also use proxy mode, the difference is that it is the first attempt to load a class, if you can not find another proxy to the parent class loader. This general class loader order is reversed. This is the recommended practice of Java Servlet specification, which aims to make Web application priority class higher than their own class Web container provides. An exception to this pattern is the agent: Java core class libraries are not within the scope of the find. This is the type of Java core libraries in order to ensure safety.

  In most cases, Web application developers need to consider associated with the class loader details. Here are a few simple principles:

  • Each Web application own Java class files and libraries used jar package, respectively, on  WEB-INF/classesand  WEB-INF/libdirectory.
  • More shared Java class files and jar package applications, Web containers were placed in the following directory specified by the share of all Web applications.
  • When an error class not found appears, check the current class of the class loader and the current thread's context class loader is correct.

 

Third, the relationship ContextClassLoader and other ClassLoader 

  We can get through this context classloader getContextClassLoader method, you can use it to load the Class we need. The default is the system classloader.

  bootstrap classloader ------- corresponding to the jvm dll write a c ++ class
  Extenson ClassLoader --------- class corresponding to the internal ExtClassLoader
  the System ClassLoader --------- inner classes corresponding to the AppClassLoader
  the Custom ClassLoader ---------- correspond to any subclass of URLClassLoader (you can also inherit SecureClassLoader or more nb little direct successor ClassLoader, so you also existence of God and the XD)

  above four classloder from top to bottom order, followed by the next parent

  to this first concept

  second concept is related classloader several classes of

           the abstract class ClassLoader
                  |
            the SecureClassLoader
                   |
            URLClassloader
             | |                
 Sun ExtClassLoader sun of the AppClassLoader
  Is the class inheritance relationship between the above, with the first concept of parent say are two different things love, need to be careful.

  The third concept is the Thread of ContextClassLoader
  fact can be seen from the name of Context, this is only a temporary storage space to store any classloader reference, nothing to do with the classloader hierarchy.

 

Four, Context ClassLoader Detailed

  Typically, a total of four kinds of class loader, i.e. the boot class loader, the EXT class loader, App class loader and a custom class loader. Class case left between them as shown in FIG., They all have different loading rules, and carried out by upwardly proxy. The article mentioned Context Class Loader is not a new loader type, but an abstract argument, its specific form: Call Thread.getCurrentThread () getContextClassLoader () that ClassLoader returned. It JVM default class and custom class loader What is the relationship between it loaded? Here an experiment to see through it.

 

 

 

3 practical exercise

(1) a step

  FIG performed on such an experiment: First called Class (1) class start MainThread (in fact, the class which has the main function of it meaning), back pay attention to the name of the class indicated in its path (i.e. ClassPath), and then tested on the inside, it is found that the current load and the current thread (MainThread) of ContextClassLoader are AppClassLoader. Then Class (1) start a new thread Class (2). Where Class (2) is a subclass of Thread, a thread of execution Class (2) I call code Thread-0.

(2) Step two

  The figure can be seen that Class (2) and the loader are equally ContextClassLoader AppClassLoader. Then I created in Class (2) in a new URLCLassLoader, and use this to load another ClassLoader and Class (1) Class Class (3) not in the same ClassPath under. At this point we can see the changes: the loaded Class (3) of the loader is URLClassLoader, and ContextClassLoader also still AppClassLoader.

(2) Step Three

  Finally, we (3) start a thread in the Class class Class (4), found that Class (4) is loaded by the URLClassLoader, but this time ContextClassLoader still AppClassLoader.

    Throughout the process, the loading of class ClassLoader changed, since the thread class Class (4) is a Class (3) starts, so that it loads the class loader becomes URLClassLoader. At the same time, all the threads ContextClassLoader inherit the generation of the thread ContextClassLoader - AppClassLoader.

 

  Code green box if we performed at the end of the second step: setContextClassLoader (), the result becomes the following way:

 

  We can clearly see that because Thread-0 is set to ContextClassLoader became URLClassLoader, and Thread-1 is generated inside the Thread-0, so it inherits its ContextClassLoader, became URLClassLoader.

 

Postscript 3

  Test listed here may not necessarily comprehensive, but I think enough to explain the problem, should be able to explain the difference ContextClassLoader other class loader is located. Discuss but there are other differences there may ContextClassLoader, there is hope that the experience of friends.

 

  . Thread.currentThread () getContextClassLoader () meaning:

  Father Classloader can use the current thread Thread.currentthread (). GetContextLoader specified classloader loaded class (). Can not be used to subvert the parent ClassLoader or other sub Classloader Classloader no direct parent-child relationship in this case loaded classes. This is the Context Class Loader significance.

 

五、Current ClassLoader

  The current class belongs ClassLoader, between the virtual machine referenced in the class, the default is to use this ClassLoader. In addition, when you use Class.forName (), Class.getResource () when these ClassLoader methods without parameters, the current class also uses the default ClassLoader. You can () method to obtain by XX.class.GetClassLoader.

 

Reference

On Context Class Loader

On ContextClassLoader

https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

http://blog.sina.com.cn/s/blog_605f5b4f01010i48.html

 http://my.oschina.net/u/571166/blog/212903

Guess you like

Origin www.cnblogs.com/goodfuture/p/11967371.html