zoukankan      html  css  js  c++  java
  • Java Se之类加载问题思考

    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class LookAtClassLoaderServlet
     */
    public class LookAtClassLoaderServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public LookAtClassLoaderServlet() {
            super();
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		PrintWriter out = response.getWriter();
    		ClassLoader classLoader = this.getClass().getClassLoader();
    		while(classLoader != null){
    			out.write(classLoader.getClass().getName() + "<br>");
    			classLoader = classLoader.getParent();
    		}
    		out.append("Served at: ").append(request.getContextPath());
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    

    这是tomcat启动之后访问此servlet打印出来的结果:

    org.apache.catalina.loader.WebappClassLoader
    java.net.URLClassLoader
    sun.misc.Launcher$AppClassLoader
    sun.misc.Launcher$ExtClassLoader
    

    将LookAtClassLoaderServlet打成jar放到jvm ext文件下,然后再重新启动tomcat,访问此servlet就会报错500。如下:

    java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
    .......
    .......
    root cause java.lang.ClassNotFoundException:javax.servlet.http.HttpServlet
    ......
    .......
    

    是因为这个servlet的父类HttpServlet也需要加载,但是这里要注意谁去加载它?回到刚开始成功的地方看一下,org.apache.catalina.loader.WebappClassLoader这是tomcat的类加载器,根据双亲委派机制,先是需要委托给父加载器让父辈们对类进行加载找不到才会往下也就是子类加载器去加载。那么上面的,LookAtClassLoaderServlet以及他的父类HttpServlet都是有org.apache.catalina.loader.WebappClassLoader进行加载的。

    当把servlet打成jar放到虚拟机的扩展目录下,那么此时sun.misc.Launcher$ExtClassLoader会进行加载,当加载到LookAtClassLoaderServlet父类HttpServlet,它并找不到。这个时候它是不会让子类去加载的所以此时只能抛出错误。(类走到哪一级类加载器加载,那么它所继承的父类同时也需要这个类加载器去加载。)

    我们知道,当HttpServlet是在…Tomcat 8.0libservlet-api.jar里面,所以此时我们将它拷贝到jdk jre的 lib 目录下ext目录下 ;重新启动 tomcat容器,进行访问,结果就成了:sun.misc.Launcher$ExtClassLoader

  • 相关阅读:
    解决Data truncation: Truncated incorrect DOUBLE value: 'xxxxxxx';
    免费LOGO在线生成+免费图床 (亲测可用)
    解决问题:bat脚本手动执行没问题,自动执行不成功
    flask上线部署————“WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.”
    钉钉机器人自动推送测试报告
    Python 自动化测试报告通过钉钉机器人推送通知
    转载:如何将新建的项目完整的提交到gitlab上?
    GIT推送时,空文件夹无法添加
    ddt+excel接口自动化测试-HtmlTestRunner报告中用例名称显示excel中自定义的名称
    Exp9 Web安全基础 20154301仉鑫烨
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608448.html
Copyright © 2011-2022 走看看