Custom ClassLoader implement Java application Core Logic module thermal deployment

Source: Internet
Author: User
Tags hadoop mapreduce

Based on the characteristics of ClassLoader and the problems encountered in the actual product environment, this paper discusses the feasibility of thermal deployment of local modules in Java applications.

We know that some Web applications provide the ability to automatically detect Mount WebApp, but most of the time, it is equivalent to restarting the WEBAPP, the data stored in memory will be lost and not flexible enough to meet the needs. The OSGi framework, while also providing thermal deployment of modules, limits applications to thermal deployment in the confines of OSGi, sometimes at a loss. So I want to customize the ClassLoader according to the actual needs, flexibly specify which class overloads, which classes do not need.

To get to the bottom of our practice, here is a brief introduction to the Java ClassLoader mechanism:

From the image above, we can see the hierarchy of the ClassLoader in the virtual machine, from the outermost classloader to the class specified by the load fully qualified name, or to the parent classloader of the ClassLoader if the load is not there, until the root ClassLoader

  Java code    protected synchronized class<?> loadclass (string name,  Boolean resolve)    throws classnotfoundexception       {    first, check if the class has already been loaded    Class c = findloadedclass (name);    if  (c == null)  {       try {       if  (parent != null)  {            c = parent.loadclass (Name, false);        } else {           &NBSP;C&NBSP;=&NBSP;FINDBOOTSTRAPCLASS0 (name);       &nbsp}        } catch  ( classnotfoundexception e)  {   &NBSP;&NBSP;&NBSP;&NBsp;    // if still not found, then invoke findclass  in order            // to find the  class.            c = findclass (name);       &nbsp}   }    if  (resolve)  {        resolveclass (c);   }    return c;       }  

  Protected synchronized class<?> loadclass (String name, Boolean resolve)
	throws ClassNotFoundException
    {
	///, check if the class has already been loaded
	Class C = findloadedclass (name);
	if (c = = null) {
	    try {
		if (parent!= null) {
		    c = parent.loadclass (name, false);
		} else {
		    c = findboot STRAPCLASS0 (name);
		}
	    catch (ClassNotFoundException e) {
	        //If still not found, then invoke Findclass into order
	        //To find the Class.
  c = Findclass (name);
	    }
	}
	if (resolve) {
	    resolveclass (c);
	}
	return c;
    }

Here our custom ClassLoader can be loaded by overloading the LoadClass method, only the classes under the specified package, and all the rest are entrusted to the parent ClassLoader, where the ClassLoader method is needed. So that our ClassLoader can load a class file at any given location.

  Java code   public class myclassloader extends classloader{   public  static concurrenthashmap<string, class<?>> classes = new  Concurrenthashmap<string, class<?>> ();       Public static mqclassloader instance = new myclassloader ();   //Construct custom classloader,  and specify parent ClassLoader    public myclassloader ()  {           super (Thread.CurrentThread (). Getcontextclassloader ());   }       public class<?> load (string name, byte[]  Data, boolean resolve)  {           class<? > klass = defineclass (name, data, 0, data.length);            if  (Resolve)  &nbsP             resolveclass (Klass);            classes.put (Name, klass);            return klass;      }           public Class<?>  LoadClass (string name, boolean resolve)  throws classnotfoundexception {            object value = classes.get (name);  //   Check Cache            if  (value != null  && value != invalid)  {                Class<?> klass =  (class<?>)  value;                if  (resolve)                     resolveclass (Klass);                return klass;               } else { //  Cache does not exist                byte[] data =  read (Findclassfile (name)); //  read class files                 if  (data == null)                     return super.loadclass (Name, resolve);  //  to parent ClassLoader to load class files                 else {                    try {                        lock.lock ();                         object cc = classes.get (name); //  Check cache                          if  (cc != null)  {                            return  (Class <?>)  cc;                         } else                  &nBsp;         return instance.load (name, data,  Resolve); //  own load class file                     } finally {                        lock.unlock ();                    }                }             }        }   }  

public class Myclassloader extends classloader{public static concurrenthashmap<string, class<?>> classes = n

EW concurrenthashmap<string, class<?>> ();
public static Mqclassloader instance = new Myclassloader ();

Constructs the custom ClassLoader and specifies the parent ClassLoader public Myclassloader () {super (Thread.CurrentThread (). Getcontextclassloader ()); Public class<?> Load (String name, byte[] data, Boolean resolve) {class<?> Klass = defineclass (name, data, 0
		, data.length);
		if (resolve) Resolveclass (Klass);
		Classes.put (name, Klass);
  Return Klass; Public class<?> loadclass (String name, Boolean resolve) throws ClassNotFoundException {Object value = Classes . get (name);
			Check cache if (value!= null && value!= INVALID) {class<?> Klass = (class<?>) value;
			if (resolve) Resolveclass (Klass);

		Return Klass; The else {//cache does not exist byte[] data = Read (Findclassfile (name));//Read class file if (data = null) return SUPER.LOADCLAss (name, resolve);
					To the parent ClassLoader the load class file else {try {lock.lock (); Object cc = classes.get (name);
					Check cache if (cc!= null) {return (class<?>) cc; else return Instance.load (name, data, resolve);
				own load class file} finally {Lock.unlock (); }
			}
		}
	}
}

The code above describes the load logic of a custom ClassLoader, Findclassfile () is the class file method that you define where you want to find it.

The DefineClass method can be flexibly used to implement distributed dynamic computing, and Hadoop MapReduce should use this method to ensure the transfer and operation of processing classes between server clusters.

Java Code/** * Reinitialization to implement the class specified by the overload/public static void Reset () {instance = new Myclassloader ();    Classes.clear (); }

      /**
	 * reinitialization to implement the class specified by the overload/public
	static void Reset () {
		instance = new Myclassloader ();
		Classes.clear ();
	}

In fact, each reset will produce a new ClassLoader instance, which will be collected in all the instances of the class is recycled after all is reclaimed, where the more unrestrained all reset off, after testing has not found a memory overflow problem.

Methods to invoke these classes:

  Java code   Public static void invoke (string method ,object[] obj,  Class<?>[] parametertypes) {           try {                object cls =  myclassloader.instance.loadclass ("Class fully qualified name",  true). newinstance ();                cls.getclass (). GetMethod ( method,parametertypes). Invoke (Cls ,obj);                        } catch  (exception e)  {                logger.error ("reloadable  error  " + method, e);                    &nbsP;&NBSP}   }  

public static void Invoke (String method, object[] obj, class<?>[] parametertypes) {
		try {
			Object cls = Myclas SLoader.instance.loadClass ("Class fully qualified name", true). Newinstance ();
			Cls.getclass (). GetMethod (Method,parametertypes). Invoke (CLS, obj);			
		catch (Exception e) {
			logger.error ("reloadable Error" + method, E);			
		}

This can only be invoked by reflection, because the ClassLoader security mechanism, the same class, the parent ClassLoader loaded class and the child ClassLoader loaded classes cannot be converted to each other.

It should be emphasized that all variables are reinitialized after overloaded class overloads, so some important data variables have to be managed by the parent ClassLoader.

There are some disadvantages in this way, the core logic is merged together, the variables are separated, thus affecting the structure of the application itself.

This approach is currently being applied to a messaging service, primarily to avoid restarting services due to minor changes, and restarting the messaging service is a hassle for large systems, and it's hard to say whether it's worth learning about 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.