设为首页 收藏本站
查看: 437|回复: 0

[经验分享] Tomcat webAppClassloader

[复制链接]

尚未签到

发表于 2017-1-15 12:32:46 | 显示全部楼层 |阅读模式
  WebappClassLoader  继承了URLClassLoader里面加入缓存和安全。
  缓存:
  1.缓存了已经事先装载的Classes。
  2.缓存了错误信息,比如先前装载一个类报错,那么下次再load这个类的时候,就会到缓存中去查找


  (   ClassNotFoundException






/**
* Load the class with the specified name.  This method searches for
* classes in the same manner as <code>loadClass(String, boolean)</code>
* with <code>false</code> as the second argument.
*
* @param name Name of the class to be loaded
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name) throws ClassNotFoundException {
return (loadClass(name, false));
}

/**
* Load the class with the specified name, searching using the following
* algorithm until it finds and returns the class.  If the class cannot
* be found, returns <code>ClassNotFoundException</code>.
* <ul>
* <li>Call <code>findLoadedClass(String)</code> to check if the
*     class has already been loaded.  If it has, the same
*     <code>Class</code> object is returned.</li>
* <li>If the <code>delegate</code> property is set to <code>true</code>,
*     call the <code>loadClass()</code> method of the parent class
*     loader, if any.</li>
* <li>Call <code>findClass()</code> to find this class in our locally
*     defined repositories.</li>
* <li>Call the <code>loadClass()</code> method of our parent
*     class loader, if any.</li>
* </ul>
* If the class was found using the above steps, and the
* <code>resolve</code> flag is <code>true</code>, this method will then
* call <code>resolveClass(Class)</code> on the resulting Class object.
*
* @param name Name of the class to be loaded
* @param resolve If <code>true</code> then resolve the class
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
if (log.isDebugEnabled())
log.debug("loadClass(" + name + ", " + resolve + ")");
Class clazz = null;
// Log access to stopped classloader
if (!started) {
try {
throw new IllegalStateException();
} catch (IllegalStateException e) {
log.info(sm.getString("webappClassLoader.stopped", name), e);
}
}
// (0) Check our previously loaded local class cache
   //在这里装载的时候使用了缓存,注意这个是local class

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
//而这个就是class

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 = system.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);
ClassLoader loader = parent;
if (loader == null)
loader = system;
try {
clazz = loader.loadClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug("  Loading class from parent");
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
}
// (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) {
;
}
// (3) Delegate to parent unconditionally
if (!delegateLoad) {
if (log.isDebugEnabled())
log.debug("  Delegating to parent classloader at end: " + parent);
ClassLoader loader = parent;
if (loader == null)
loader = system;
try {
clazz = loader.loadClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug("  Loading class from parent");
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
}
throw new ClassNotFoundException(name);
}
   看看WebAppClassLoader是如何从缓存中装载的

    /**
* Finds the class with the given name if it has previously been
* loaded and cached by this class loader, and return the Class object.
* If this class has not been cached, return <code>null</code>.
*
* @param name Name of the resource to return
*/
protected Class findLoadedClass0(String name) {
//resouceEntries是个hashmap

ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
if (entry != null) {
return entry.loadedClass;
}
return (null);  // FIXME - findLoadedResource()
}

//看看缓存对象的代码
import java.net.URL;
import java.security.cert.Certificate;
import java.util.jar.Manifest;
/**
* Resource entry.
*
* @author Remy Maucherat
* @version $Revision: 302726 $ $Date: 2004-02-27 15:59:07 +0100 (ven., 27 f茅vr. 2004) $
*/
public class ResourceEntry {

/**
* The "last modified" time of the origin file at the time this class
* was loaded, in milliseconds since the epoch.
*/
public long lastModified = -1;

/**
* Binary content of the resource.
*/
public byte[] binaryContent = null;

/**
* Loaded class.
*/
public Class loadedClass = null;

/**
* URL source from where the object was loaded.
*/
public URL source = null;

/**
* URL of the codebase from where the object was loaded.
*/
public URL codeBase = null;

/**
* Manifest (if the resource was loaded from a JAR).
*/
public Manifest manifest = null;

/**
* Certificates (if the resource was loaded from a JAR).
*/
public Certificate[] certificates = null;
}


   安全机制



/**
* The set of trigger classes that will cause a proposed repository not
* to be added if this class is visible to the class loader that loaded
* this factory class.  Typically, trigger classes will be listed for
* components that have been integrated into the JDK for later versions,
* but where the corresponding JAR files are required to run on
* earlier versions.
*/
protected static final String[] triggers = {
"javax.servlet.Servlet"                     // Servlet API
};
//这个在Tomcat4中有,在tomcat6.0中没有

private static final String[] packageTriggers = {
"javax",                                     // Java extensions
"org.xml.sax",                               // SAX 1 & 2
"org.w3c.dom",                               // DOM 1 & 2
"org.apache.xerces",                         // Xerces 1 & 2
"org.apache.xalan"                           // Xalan
};




 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-328824-1-1.html 上篇帖子: tomcat ssl 下篇帖子: tomcat ClassNotFoundException
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表