一直认为tomcat5的类加载器的toString方法很酷,为什么呢?因为它的toString方法列出了所有的父类加载器以及类加载器加载的资源(即classpath).可能有些朋友还没有注意过,如果想看看它到底有多酷的话可以随便找个jsp
<%System.out.println(com.syj.Test.class.getClassLoader());%>

WEB-INF/classes/com/syj/Test

启动tomcat访问jsp,看看控制台:

信息: Exposing service with name {http://ws.syj.com}Demo
2008-9-20 16:15:32 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2008-9-20 16:15:33 org.apache.jk.common.ChannelSocket init
信息: JK2: ajp13 listening on /0.0.0.0:8009
2008-9-20 16:15:33 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=15/78  config=D:/SYJ.WORK/SYJ.SERVER/tomcat5/conf/jk2.properties
2008-9-20 16:15:33 org.apache.catalina.startup.Catalina start
信息: Server startup in 6907 ms

转载请注明出处http://blog.csdn.net/sunyujia/
WebappClassLoader
  delegate: false
  repositories:
    /WEB-INF/classes/
----------> Parent Classloader:
StandardClassLoader
  delegate: true
  repositories:
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/shared/classes/
----------> Parent Classloader:
StandardClassLoader
  delegate: true
  repositories:
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/classes/
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/ant-launcher.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/ant.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/commons-collections-3.1.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/commons-dbcp-1.2.1.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/commons-el.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/commons-pool-1.2.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/jasper-compiler.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/jasper-runtime.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/jsp-api.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/mssql_All.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/naming-common.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/naming-factory.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/naming-java.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/naming-resources.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/servlet-api.jar
    file:D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/tools.jar
----------> Parent Classloader:
sun.misc.Launcher$AppClassLoader@18d107f

非常清晰的调试信息,classpath一目了然,在一些复杂的类加载场景非常有用,

反编译tomcat5/server/lib/catalina.jar/WebappClassLoader.class 类查看源码

  1. public String toString()
  2. {
  3. StringBuffer sb = new StringBuffer("WebappClassLoader/r/n");
  4. sb.append("  delegate: ");
  5. sb.append(_flddelegate);
  6. sb.append("/r/n");
  7. sb.append("  repositories:/r/n");
  8. if(repositories != null)
  9. {
  10. for(int i = 0; i < repositories.length; i++)
  11. {
  12. sb.append("    ");
  13. sb.append(repositories[i]);
  14. sb.append("/r/n");
  15. }
  16. }
  17. if(parent != null)
  18. {
  19. sb.append("----------> Parent Classloader:/r/n");
  20. sb.append(parent.toString());
  21. sb.append("/r/n");
  22. }
  23. return sb.toString();
  24. }

so easy,于是就想写个Util类,搞个 public static String toString(ClassLoader classLoader) 方法,说干就干,不过repositories这个属性是tomcat自己搞的,在sun提供的类加载器中,哪个属性存储了classpath呢?我可没兴趣翻阅tomcat类加载过程的源码,于是在debug下,内存里面找了一通,发现原来是存储在URLClassLoader的URLClassPath ucp属性中,虽然不是public的,但是没有关系,因为可以靠反射取得,反射可是干这个的强项,呵呵,代码不多,贴出来和大家一起分享成果.

  1. import java.io.File;
  2. import java.lang.reflect.Field;
  3. import java.net.URL;
  4. import java.net.URLClassLoader;
  5. import java.util.List;
  6. /**
  7. * <p>
  8. * Title:调试辅助类
  9. * </p>
  10. *
  11. * <p>
  12. * Description:
  13. * </p>
  14. *
  15. * <p>
  16. * Copyright: 转载请注明出处http://blog.csdn.net/sunyujia/
  17. * </p>
  18. *
  19. * @author 孙钰佳
  20. * @main sunyujia@yahoo.cn
  21. * @date Sep 20, 2008 3:27:23 PM
  22. */
  23. public class DebugUtil {
  24. /**
  25. *
  26. * Description:将类加载器转换为字符串,用于打印,调试程序使用.
  27. * 转载请注明出处http://blog.csdn.net/sunyujia/
  28. *
  29. * @mail sunyujia@yahoo.cn
  30. *
  31. * @since:Sep 20, 2008 3:29:59 PM
  32. */
  33. public static String toString(ClassLoader classLoader) {
  34. StringBuffer sb = new StringBuffer(classLoader.getClass().getName());
  35. sb.append("/r/n");
  36. try {
  37. Field[] fields = URLClassLoader.class.getDeclaredFields();// 取出URLClassLoader类加载器的全部属性
  38. for (int i = 0; i < fields.length; i++) {// 遍历属性
  39. Field field = fields[i];
  40. if (field.getName().equals("ucp")) {// 找到ucp属性Field对象
  41. field.setAccessible(true);// 打开访问权限
  42. final Object ucp = field.get(classLoader);// 取得类加载器中的ucp对象
  43. Field[] ucpFields = ucp.getClass().getDeclaredFields();// 取ucp对象的全部属性
  44. for (int k = 0; k < ucpFields.length; k++) {// 遍历ucp对象的属性
  45. ucpFields[k].setAccessible(true);// 打开访问权限
  46. if (ucpFields[k].getName().equals("path")) {// 取得ucp对象中的path属性Field对象
  47. List list = (List) ucpFields[k].get(ucp);// 取得ucp对象中的path对象
  48. sb.append("  repositories:/r/n");
  49. for (int j = 0; j < list.size(); j++) {
  50. sb.append("    ");
  51. sb.append(list.get(j));
  52. sb.append("/r/n");
  53. }
  54. }
  55. }
  56. }
  57. }
  58. if (classLoader.getParent() != null) {
  59. sb.append("----------> Parent Classloader:/r/n");
  60. sb.append(toString(classLoader.getParent()));// 递归
  61. sb.append("/r/n");
  62. }
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. }
  66. return sb.toString();
  67. }
  68. public static void main(String[] args) throws Exception {
  69. File file1 = new File(
  70. "D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/ant.jar");
  71. File file2 = new File(
  72. "D:/SYJ.WORK/SYJ.SERVER/tomcat5/webapps/WebServicesDemo/WEB-INF/classes");
  73. URLClassLoader mcl = new URLClassLoader(new URL[] {
  74. file1.toURI().toURL(), file2.toURI().toURL() });
  75. System.out.println("演示1:");
  76. System.out
  77. .println(DebugUtil.toString(DebugUtil.class.getClassLoader()));
  78. System.out.println("演示2:");
  79. Class clazz = mcl.loadClass("com.syj.Test");
  80. System.out.println(DebugUtil.toString(clazz.getClassLoader()));
  81. }
  82. }

程序输出结果:

演示1:
sun.misc.Launcher$AppClassLoader
  repositories:
    file:/D:/SYJ.WORK/SYJ.WORKSPACE/ws1/MyblogTest/bin/
----------> Parent Classloader:
sun.misc.Launcher$ExtClassLoader
  repositories:
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/dnsns.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/localedata.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunjce_provider.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunmscapi.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunpkcs11.jar

演示2:
java.net.URLClassLoader
  repositories:
    file:/D:/SYJ.WORK/SYJ.SERVER/tomcat5/common/lib/ant.jar
    file:/D:/SYJ.WORK/SYJ.SERVER/tomcat5/webapps/WebServicesDemo/WEB-INF/classes/
----------> Parent Classloader:
sun.misc.Launcher$AppClassLoader
  repositories:
    file:/D:/SYJ.WORK/SYJ.WORKSPACE/ws1/MyblogTest/bin/
----------> Parent Classloader:
sun.misc.Launcher$ExtClassLoader
  repositories:
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/dnsns.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/localedata.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunjce_provider.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunmscapi.jar
    file:/D:/SYJ.WORK/SYJ.ENV/jdk6.0/jre/lib/ext/sunpkcs11.jar

利用反射模拟Tomcat类加载器的toString方法相关推荐

  1. Tomcat类加载器机制

    Tomcat为什么需要定制自己的ClassLoader: 1.定制特定的规则:隔离webapp,安全考虑,reload热插拔 2.缓存类 3.事先加载 要说Tomcat的Classloader机制,我 ...

  2. JVM类加载理解(线程上下文类加载器、Tomcat类加载器)

    类加载机制概念 Java虚拟机把描述类的class文件加载到内存,对其进行校验.转换解析.初始化等操作,最终得到可以被虚拟机直接使用的java类型,这就是虚拟机的加载机制. 主要有五个步骤: 加载 将 ...

  3. Tomcat类加载器为何违背双亲委派模型

    本文来说下Tomcat类加载器为何违背双亲委派模型 文章目录 什么是类加载机制 什么是双亲委派模型 如何破坏双亲委任模型 Tomcat的类加载器是怎么设计的 本文小结 什么是类加载机制 代码编译的结果 ...

  4. 接口多个实现类加载哪个_深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  5. python post请求 上传图片_利用python模拟实现POST请求提交图片的方法

    本文主要给大家介绍的是关于利用python模拟实现POST请求提交图片的方法,分享出来供大家参考学习,下面来一看看详细的介绍: 使用requests来模拟HTTP请求本来是一件非常轻松的事情,比如上传 ...

  6. python paste_利用Python模拟登录pastebin.com的实现方法

    任务 在https://pastebin.com网站注册一个账号,利用python实现用户的自动登录和创建paste.该任务需要分成如下两步利用python实现: 1.账号的自动登录 2.paste的 ...

  7. 类加载机制:双亲委任模型和tomcat类加载器

    简介 类是如何加载的,那么必须要面对的几个问题如下 什么是类加载机制? 什么是双亲委任模型? 如何破坏双亲委任模型? Tomcat 的类加载器是怎么设计的? 类加载机制 Java 中的类加载器大致可以 ...

  8. Tomcat源码解析六:Tomcat类加载器机制

    要说Tomcat的Classloader机制,我们还得从Bootstrap开始.在BootStrap初始化的时候,调用了org.apache.catalina.startup.Bootstrap#in ...

  9. Javascript 的函数式对象(三)利用闭包模拟类的静态变量和方法

    除了模拟类的私有变量和私有方法.闭包还可用来模拟类的静态变量和方法. 除了再次利用js的闭包特性,还需要借助js语法上的一些特点. 执行上述代码后,浏览器控制台将会输出如下字符串: Created 1 ...

最新文章

  1. IP 网络性能的度量标准
  2. python快速入门答案-Python 快速入门笔记(1):简介
  3. 软件工程方法论为我们经软件开发有多大用处?谈谈你的看法。
  4. LInux之建立文件和目录
  5. 软考系统架构师笔记-最后知识点总结(一)
  6. 【英语学习】【WOTD】liaison 释义/词源/示例
  7. Checkbox与RadioGroup的使用方法
  8. ICC_lab总结——ICC_lab3:布局
  9. 2013年最新黑马程序员全套视频-.net视频40G免费下
  10. 条码检测系统——基于MATLAB的一维条码识别
  11. 简洁UI好玩的文字转换emoji表情微信小程序源码下载支持句子词语转换
  12. 笔记本(无线网卡)配置虚拟机上网
  13. 沧海云帆服务器哪里的,11月沧海云帆大区天涯合璧-数据互通(合服)服务器维护公告(已完成)...
  14. 2022 Medtec中国展参观渠道开放,800+参展企业将助力稳定供应链
  15. 树莓派控制4路5v继电器开关
  16. 微型计算机原理中BX是什么,微型计算机原理第7章答案
  17. HDU 2448 Mining Station on the Sea 最短路+KM
  18. 各类3D建模格式转换gltf格式【来源一个建模APP客户问题解决】
  19. 2019软件测试自学必看
  20. Linux傲腾DC128G内存设置,Intel发布傲腾DC非易失性内存:3DXpoint、128GB起、服务器专用...

热门文章

  1. ​2022年云市场营收排行榜
  2. H5页面在iphone手机底部出现留白的情况
  3. Stata:多个变量组间均值\中位数差异检验
  4. 软件质量测试中的健壮性测试是什么?一文和你说
  5. 微信聊天记录云储存服务怎么开通使用?
  6. Verilog功能模块——取滑动平均值(使用FIFO)
  7. 如何理解Liveupdate Administrator (LUA) 下SEP的更新文件
  8. Matplotlib折线图线型设置
  9. 搜索与图论1—深搜、宽搜、拓扑排序
  10. 用易我分区表医生恢复破坏的分区表