java classloader graded loading jar

 

    java classloader graded loading sample.

CustomClassder is used as the loader of the app jar package, and the parallel loading option is turned on.    

 

package com.jsun;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * Custom classloader
 */
public class CustomClassder extends URLClassLoader {

    public CustomClassder(URL[] urls, ClassLoader parent) {
        super(urls, parent);
   }
    public static void register (){
        try{
            final Method registerParallel =
                    ClassLoader.class.getDeclaredMethod("registerAsParallelCapable");
            registerParallel.setAccessible(true);
            registerParallel.invoke(null);
        }catch (Exception e){
            e.printStackTrace ();
        }

    }

}

 

 CustomClassder inherits URLClassLoader, so as long as the constructor passes in the appjar address that needs to be loaded, then the second parameter is the classloader of the current thread, currently appclassloader

 

package com.jsun;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;

public class test {


    public static void main(String[] arg)throws Exception{

        String jar = "G:\\workspace\\myclassloader\\outjar\\test.jar";
        File file = new File(jar);
        URL url = file.toURI (). ToURL ();

        CustomClassder.register();
        CustomClassder classder = new CustomClassder(new URL[]{url},Thread.currentThread().getContextClassLoader());
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                runApp();
            }
        });
        thread.setContextClassLoader(classder);
        thread.start();
    }

    public static void runApp (){
        try {
            Class appstartClass = Thread.currentThread().getContextClassLoader().loadClass("com.TestBean");
            Object app = appstartClass.newInstance();
            Method method = appstartClass.getMethod("appStartRun");
            String appRunResult = (String) method.invoke(app,null);
            System.out.println(appRunResult);
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }
}

 CustomClassder.register() registers the CustomClassder in the parallel single-grain class ParallelLoaders, and calls

CustomClassder.register() is currently appclassloader, and then uses the instance of
appclassloader to register CustomClassder for ParallelLoaders. So when creating a new CustomClassder

private ClassLoader(Void unused, ClassLoader parent) {
        this.parent = parent;
        if (ParallelLoaders.isRegistered(this.getClass())) {
            parallelLockMap = new ConcurrentHashMap<>();
            package2certs = new ConcurrentHashMap<>();
            domains =
                Collections.synchronizedSet(new HashSet<ProtectionDomain>());
            assertionLock = new Object();
        } else {
            // no finer-grained lock; lock on the classloader instance
            parallelLockMap = null;
            package2certs = new Hashtable<>();
            domains = new HashSet<>();
            assertionLock = this;
        }
    }

 ParallelLoaders.isRegistered in Classloader can get CustomClassder.class so CustomClassder becomes a parallel loader.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326248892&siteId=291194637