重写webAppClassLoader

来源:互联网 发布:vb.net和asp.net区别 编辑:程序博客网 时间:2024/04/29 07:57

     由于webappclassloader并没有遵循双亲委派类型,使用javaagent加载进来的类(由系统类加载器加载),会在webappclassloader中重新加载一次,所以需要重写webappclassloader。

     首先,写一个classLoader继承自webAppClassLoader。重写loadClass方法,并且需要重写构造函数来指定父加载器。代码如下:

package org.apache.catalina.loader;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;public class MyClassLoader extends org.apache.catalina.loader.WebappClassLoader {   public MyClassLoader(){   super();   }   public MyClassLoader(ClassLoader parent) {   super(parent);   }  @Override    public synchronized Class<?> loadClass(String name, boolean resolve)        throws ClassNotFoundException {        Class<?> clazz = null;        if (!started) {            try {                throw new IllegalStateException();            } catch (IllegalStateException e) {                log.info(sm.getString("webappClassLoader.stopped", name), e);            }        }//修改为从系统类的缓存中加载             if(name.equals("com.hook.Agent")){        String className = "com.hook.Agent";        return  ClassLoader.getSystemClassLoader().loadClass(className);        }        // (0) Check our previously loaded local class cache        clazz = findLoadedClass0(name);        if (clazz != null) {            if (log.isDebugEnabled())                log.debug("  Returning class from cache");            if (resolve)                resolveClass(clazz);            return (clazz);        }        // (0.1) Check our previously loaded class cache        clazz = findLoadedClass(name);        if (clazz != null) {            if (log.isDebugEnabled())                    log.debug("  Returning class from cache");            if (resolve)                resolveClass(clazz);            return (clazz);        }        // (0.2) Try loading the class with the system class loader, to prevent        //       the webapp from overriding J2SE classes        try {            clazz = j2seClassLoader.loadClass(name);            if (clazz != null) {                if (resolve)                    resolveClass(clazz);                return (clazz);            }        } catch (ClassNotFoundException e) {            // Ignore        }        // (0.5) Permission to access this class when using a SecurityManager        if (securityManager != null) {            int i = name.lastIndexOf('.');            if (i >= 0) {                try {                    securityManager.checkPackageAccess(name.substring(0,i));                } catch (SecurityException se) {                    String error = "Security Violation, attempt to use " +                        "Restricted Class: " + name;                 //   log.info(error, se);                    throw new ClassNotFoundException(error, se);                }            }        }        boolean delegateLoad = delegate || filter(name);        // (1) Delegate to our parent if requested        if (delegateLoad) {            if (log.isDebugEnabled())                log.debug("  Delegating to parent classloader1 " + parent);            try {                clazz = Class.forName(name, false, parent);                if (clazz != null) {                    if (log.isDebugEnabled())                        log.debug("  Loading class from parent");                    if (resolve)                        resolveClass(clazz);                    return (clazz);                }            } catch (ClassNotFoundException e) {                // Ignore            }        }        // (2) Search local repositories        if (log.isDebugEnabled())            log.debug("  Searching local repositories");        try {            clazz = findClass(name);            if (clazz != null) {                if (log.isDebugEnabled())                    log.debug("  Loading class from local repository");                if (resolve)                    resolveClass(clazz);                return (clazz);            }        } catch (ClassNotFoundException e) {            // Ignore        }        // (3) Delegate to parent unconditionally        if (!delegateLoad) {            if (log.isDebugEnabled())                log.debug("  Delegating to parent classloader at end: " + parent);            try {                clazz = Class.forName(name, false, parent);                if (clazz != null) {                    if (log.isDebugEnabled())                        log.debug("  Loading class from parent");                    if (resolve)                        resolveClass(clazz);                    return (clazz);                }            } catch (ClassNotFoundException e) {                // Ignore            }        }        throw new ClassNotFoundException(name);    }}

然后配置tomcat的context.xml,在context标签内加上Loader,指向自己的类名。

 <Loader loaderClass="org.apache.catalina.loader.MyClassLoader" />  

最后把类加载器打成jar包后放到tomcat/lib下。

重新启动tomcat后即可使用自己的类加载器。

0 0
原创粉丝点击