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

[经验分享] Tomcat 5.0.18 ClassLoader source code insight

[复制链接]

尚未签到

发表于 2017-2-7 06:58:17 | 显示全部楼层 |阅读模式
  All the functionality of ClassLoader is nested in org.apache.catalina.loader.WebappClassLoader
  1) Structure of WebappClassLoader

public class WebappClassLoader
extends URLClassLoader
implements Lifecycle{
/**
* The cache of ResourceEntry for classes and resources we have loaded,
* keyed by resource name.
*/
protected HashMap resourceEntries = new HashMap();
/**
* The list of not found resources.
*/
protected HashMap notFoundResources = new HashMap();
public Class loadClass(String name, boolean resolve);
protected Class findLoadedClass0(String name);
public Class findClass(String name);
protected Class findClassInternal(String name);
// This method is derived from java.lang.ClassLoader; it will invoke native method searching JVM for classes loaded by current class loaders
// It will return the loaded class if and only if the class is previously loaded(call defineClass method) by current class loader instance
protected final Class<?> findLoadedClass(String name);
// This method is derived from java.lang.ClassLoader, it will invoke native method  and it is the only way of converting byte[] into Class<?>; even if in our self defined ClassLoader.
protected final Class<?> defineClass(String name, byte[] b, int off, int len,
ProtectionDomain protectionDomain);
}
  2) Overrides loadClass() on URLClassLoader

public Class loadClass(String name, boolean resolve){
// (0) Check local class cache
clazz = findLoadedClass0(name);
if (clazz != null) {
return (clazz);
}
// (0.1) Check ClassLoader inherent cache, call native method
clazz = findLoadedClass(name);
if (clazz != null) {
return (clazz);
}
// Here we can guarantee that target class hasn't been loaded by WebAppClassLoader before, but whether it has been loaded by System/Ext/Bootstrap ClassLoader is unknown
// Try to find class from bootstrap/ext/system ClassLoader's inherent cache, if cannot find, try to load .class from class path; throw exception when cannot be load either
try {
clazz = system.loadClass(name);
return (clazz);
} catch (ClassNotFoundException e) {
// Ignore
}
// Here we are sure that the target class hasn't loaded by current application before.
// We will try to load it from container's WEB-INF/libs
// delegateLoad means WebappClassLoader will use parent first model, if false, means WebappClassLoader will use child first model.
boolean delegateLoad = delegate || filter(name);
// load class with parent
if (delegateLoad) {
try{
clazz = parent.loadClass(name);
if (clazz != null) {
return (clazz);
}
}catch(ClassNotFoundException e){
// swallow e
}
}
// load class with child(It is the end of parent delegation, and it is the start of child first)
try {
clazz = findClass(name);
if (clazz != null) {
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
// load class with parent(It is then end of child first model)
if (!delegateLoad) {
ClassLoader loader = parent;
try {
clazz = loader.loadClass(name);
if (clazz != null) {
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
}
// All possible tries has failed, throw exception
throw new ClassNotFoundException(name);
}
// get class from WebappClassLoader customized class cache
protected Class findLoadedClass0(String name) {
ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
if (entry != null) {
return entry.loadedClass;
}
return (null);  // FIXME - findLoadedResource()
}
  3) How tomcat class reload works? Take a look at WebappClassLoader.stop()/start() as it implements interface Lifecycle;

// All ClassLoader did is clear its local class cache because we do not have the access to inherited java.lang.ClassLoader's inherent cache.
// reload is realized by calling stop() and start(), then loadClass() loading all classes under WEB-INF/lib
// loadClass(name) will first check local class cache which will return null, then it will check inherent cache, that would return "null" because
// every time we restart, our WebappClassLoader is newly instantiated(the old instance is discarded)
public void stop(){
started = false;
notFoundResources.clear();
resourceEntries.clear();
repositoryURLs = null;
}
public void start() throws LifecycleException {
started = true;
}
  The logic where a new WebappClassLoader instance is created every time the container is restarted:

// WebappLoader
public void start(){
classLoader = createClassLoader();
classLoader.setResources(container.getResources());
classLoader.setDebug(this.debug);
classLoader.setDelegate(this.delegate);
// ...
if (classLoader instanceof Lifecycle)
((Lifecycle) classLoader).start();
}
/**
* Create associated classLoader.
*/
private WebappClassLoader createClassLoader()
throws Exception {
Class clazz = Class.forName(loaderClass);
WebappClassLoader classLoader = null;
if (parentClassLoader == null) {
parentClassLoader = Thread.currentThread().getContextClassLoader();
}
Class[] argTypes = { ClassLoader.class };
Object[] args = { parentClassLoader };
Constructor constr = clazz.getConstructor(argTypes);
classLoader = (WebappClassLoader) constr.newInstance(args);
return classLoader;
}
  Summary:
  1) We do not have direct access to native class cache defined by JVM. But we can make a little tweaks to realize class loading:
  1> We can suppose the native class cache keeps a map of Map<String, Class> with key of ClassLoader.instance.hashCode[classname+instancecode], and value of loaded class.
  2> The class would be recorded into native cache when the class loader's instance calls defineClass(), and the cached class would be returned only when current class loader instance calls findLoadedClass0();

运维网声明 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-338471-1-1.html 上篇帖子: Xfire + JDK1.5 + MyEclipse + Tomcat 构建webservice服务 下篇帖子: Tomcat下JSP、Servlet和JavaBean环境的配置(初学必掌握的哦)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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