2013年11月19日星期二

Thread ' getContextClassLoader ()

Forget previously had not asked this question , in short, I now have seen a few places have this :
Thread.currentThread (). getContextClassLoader ()
I always think in what circumstances would use this way to get a ClassLoader, because it seems to default, it returns the ClassLoader and load applications are the same , for example, to write in a class Test
ClassLoader cl = Thread.currentThread (). getContextClassLoader ();
Why not just use Test.class.getClassLoader ()

get the current context class loader is do you mean ? Yousha benefits ?
------ Solution --------------------- -----------------------
http://stackoverflow.com/questions/676250/different-ways-of-loading-a-file-as-an-inputstream
------ Solution ---------------------------------------- ----
http://uule.iteye.com/blog/813841 < br> ------ Solution ----------------------------------------- ---
Suppose you want to load the class, through the chain of the current class Classloader loaded or not, it would have to set up ContextClassLoader
------ Solution -------------- ------------------------------
Classloader chain through the current class can not be loaded , it may establish ContextClassLoader
------ Solution ------------------------------------------- -

public class Test {

public static void main(String[] args) {

// 此时三个ClassLoader是同一个对象
System.out.println(Thread.currentThread().getContextClassLoader()); // 当前线程的类加载器
System.out.println(Test.class.getClassLoader()); // 当前类的类加载器
System.out.println(ClassLoader.getSystemClassLoader()); // 系统初始的类加载器

}
}

If the landlord understood the openfire should ClassLoader a relatively deep understanding.
make a simple example, you are a WEB program , publish to Tomcat running inside .
The first is the implementation of Tomcat org.apache.catalina.startup.Bootstrap class , this time the class loader is ClassLoader.getSystemClassLoader ().
The WEB program behind us , inside the jar, resources are made within Tomcat to load , so you loaded dynamically in code jar, resource files , the first should be to use Thread.currentThread (). getContextClassLoader ( ) . If you use Test.class.getClassLoader (), may cause the current thread is running class loader inconsistent ( because Java inherently multithreaded ) .
Test.class.getClassLoader () is generally used in getResource, because you want to get a resource file, the resource file's location is relatively fixed .

proposed landlord to look openfire or tomcat internal source, the ClassLoader will be relatively deep understanding.
inside the openfire , openfire use class loader , and each plug-in uses the class loader is not the same .

------ Solution ------------------------------------ --------

final ClassLoader parent = findParentClassLoader();

            String libDirString = System.getProperty("openfire.lib.dir");

            File libDir;
            if (libDirString != null) {
                // If the lib directory property has been specified and it actually
                // exists use it, else use the default
                libDir = new File(libDirString);
                if (!libDir.exists()) {
                    Log.warn("Lib directory " + libDirString +
                            " does not exist. Using default " + DEFAULT_LIB_DIR);
                    libDir = new File(DEFAULT_LIB_DIR);
                }
            }
            else {
                libDir = new File(DEFAULT_LIB_DIR);
            }

            // Unpack any pack files.
            unpackArchives(libDir, true);

            String adminLibDirString = System.getProperty("openfireHome");
            if (adminLibDirString == null) {
                adminLibDirString = DEFAULT_ADMIN_LIB_DIR;
            }
            else {
                adminLibDirString = adminLibDirString+"/plugins/admin/webapp/WEB-INF/lib";
            }
            File adminLibDir = new File(adminLibDirString);
            if (adminLibDir.exists()) {
                unpackArchives(adminLibDir, false);
            }
            else {
                Log.warn("Admin Lib Directory " + adminLibDirString +
                    " does not exist. Web admin console may not work.");
            }

            ClassLoader loader = new JiveClassLoader(parent, libDir);

            Thread.currentThread().setContextClassLoader(loader);
            Class containerClass = loader.loadClass(
                    "org.jivesoftware.openfire.XMPPServer");
            containerClass.newInstance();

------ For reference only ------------------------ ---------------

For example look
------ For reference only ----------- ----------------------------
try to answer this question,
java class loading mechanism (jvm specification ) was commissioned by the model , simply put , if you want a class loader loads a class , first it will delegate to its parent to load , if not all of its parent successful load then it will come personally , I kinda feel like the son beck and call . . jvm also fight father ah , ,
There are three classes in the default jvm loaer, bootstrap, ext, app, of which the largest is the grandfather boot , app smallest grandson , ext middle is the father .
They have access to the classpath are not the same , boot is below jdk or jre lib directory , ext is the jdk or jre ext directory, app path specified by the user , such as using -cp parameter specifies the directory or jar. They do not have authority to access other people's classpath, this question came a bird , someone may ask the commander adults bored egg hurt the dog , get so complicated , allegedly for security reasons , to avoid erosion of the user's code nausea meaning jvm, the problem is that when the bootstrap or ext want to load user-specified classpath classes will fail, because maybe the goods do not have permission delegation app path class , so we have spent so much a nondescript contextloader. . . .

没有评论:

发表评论