tomcat 7 中的类加载器学习
tomcat 7自带很多junit测试用例,可以帮助我们窥探源码的秘密。以下使用来测试类加载器的一个测试用例。类加载器也是对象,他们用来将类从类从。class文件加载到虚拟机,这些已经讲了很多,深入jvm中说的很详细,什么双亲委派模型,在书中还以tomcat为例讲解。
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.catalina.loader;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.util.buf.ByteChunk;
public class TestWebappClassLoader extends TomcatBaseTest {
@Test
public void testGetURLs() throws Exception {
File f = new File("test/webresources/war-url-connection.war");
String[] expected = new String[2];
String warUrl = f.toURI().toURL().toExternalForm();
expected[0] = "jar:" + warUrl + "!/WEB-INF/classes/";
expected[1] = "jar:" + warUrl + "!/WEB-INF/lib/test.jar";
Tomcat tomcat = getTomcatInstance();
// Must have a real docBase - just use temp
StandardContext ctx =
(StandardContext)tomcat.addContext("", f.getAbsolutePath());
tomcat.start();
//获得当前的类加载器
ClassLoader cl = ctx.getLoader().getClassLoader();
Assert.assertTrue(cl instanceof URLClassLoader);
//获得类加载器中对应的路径
try (URLClassLoader ucl = (URLClassLoader) cl) {
URL[] urls = ucl.getURLs();
Assert.assertEquals(expected.length, urls.length);
String[] actual = new String[urls.length];
for (int i = 0; i < urls.length; i++) {
actual[i] = urls[i].toExternalForm();
System.out.println(actual[i]);
}
Assert.assertArrayEquals(expected, actual);
//获得类加载器的各级父类加载器
while(cl!=null)
{
System.out.println(cl);
cl=cl.getParent();
}
}
}
@Test
public void testBug53454() throws Exception {
Tomcat tomcat = getTomcatInstance();
// Must have a real docBase - just use temp
StandardContext ctx = (StandardContext)
tomcat.addContext("", System.getProperty("java.io.tmpdir"));
System.out.println("临时目录"+System.getProperty("java.io.tmdir"));
// Map the test Servlet
MyServlet largeBodyServlet = new MyServlet();
Tomcat.addServlet(ctx, "MyServlet", largeBodyServlet);
ctx.addServletMapping("/", "MyServlet");
tomcat.start();
Map<String,List<String>> resHeaders= new HashMap<>();
int rc = headUrl("http://localhost:" + getPort() + "/", new ByteChunk(),
resHeaders);
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
ClassLoader cl=ctx.getClass().getClassLoader();
while(cl!=null)
{
System.out.println(cl);
cl=cl.getParent();
}
}
private static class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
}
输出结果:
临时目录null sun.misc.Launcher$AppClassLoader@4bb8d481
sun.misc.Launcher$ExtClassLoader@538787fd jar:file:/F:/javal/Tomcat-Research-trunk/test/webresources/war-url-connection.war!/WEB-INF/classes/
jar:file:/F:/javal/Tomcat-Research-trunk/test/webresources/war-url-connection.war!/WEB-INF/lib/test.jar
WebappClassLoader
context:
delegate: false
----------> Parent Classloader:
sun.misc.Launcher$AppClassLoader@4bb8d481 sun.misc.Launcher$AppClassLoader@4bb8d481
sun.misc.Launcher$ExtClassLoader@538787fd
一月 26, 2015 6:52:56 下午 org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-nio-127.0.0.1-auto-2-64075"]
一月 26, 2015 6:52:56 下午 org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-nio-127.0.0.1-auto-2-64075"]
如果使用临时目录和默认目录,应用的类加载器是AppClassLoader,而其的目录可以每个应用的类加载器为WebappClassLoader
tomcat 7 中的类加载器学习的更多相关文章
- Java中的类加载器以及Tomcat的类加载机制
在加载阶段,虚拟机需要完成以下三件事情: 1.通过一个类的全限定名来获取其定义的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 3.在Java堆中生成一个代表这个类 ...
- Java中的类加载器--Class loader
学习一下Java中的类加载器,这个是比较底层的东西,好好学习.理解一下. 一.类加载器的介绍 1.类加载器:就是加载类的工具,在java程序中用到一个类,java虚拟机首先要把这个类的字节码加载到内 ...
- [读书笔记]java中的类加载器
以下内容大多来自周志明的<深入理解Java虚拟机>. 类加载器是java的一项创新,也是java流行的重要原因之一,它最初是为了满足java applet的需求而开发出来. 什么是appl ...
- Java中的类加载器
转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制 我们知道,Java是一种动态语言.那么怎 ...
- 简单了解Tomcat与OSGi的类加载器架构
前言: 本次博客主要是对Tomcat与OSGi的类加载器架构,所以就需要对tomcat.OSGi以及类加载机制有所了解 类加载可以在http://www.cnblogs.com/ghoster/p/7 ...
- Android插件基础之类加载器学习
记录学习java 加载器学习所获心得,逐步记录了解java加载器的过程.为了知悉android 插件化的实现原理,从而需要从头了解android加载apk,以及基础的java类加载的加载过程情况,为方 ...
- Tomcat与spring的类加载器案例
Tomcat与spring的类加载器案例接下来将介绍<深入理解java虚拟机>一书中的案例,并解答它所提出的问题.(部分类容来自于书中原文) Tomcat中的类加载器在Tomcat目录结构 ...
- java中的类加载器ClassLoader和类初始化
每个类编译后产生一个Class对象,存储在.class文件中,JVM使用类加载器(Class Loader)来加载类的字节码文件(.class),类加载器实质上是一条类加载器链,一般的,我们只会用到一 ...
- Java中的类加载器----ClassLoader
1.简单的讲类加载器就是加载类. 在一个类要被执行时,首先会被从硬盘中加载到内存中,这个任务就是由类加载器来完成,如果加载不成功时,类是无法被执行的.类加载器执行的都是字节码二进制文件. 帮助文档 ...
随机推荐
- spoj 95
栈应用 ...... 水题 #include<cstdio> #include<cstdlib> #include<cstring> #include<alg ...
- 10 things you should know about NoSQL databases
For a quarter of a century, the relational database (RDBMS) has been the dominant model for database ...
- POJ 1091 跳蚤 容斥原理
分析:其实就是看能否有一组解x1,x2, x3, x4....xn+1,使得sum{xi*ai} = 1,也就是只要有任意一个集合{ai1,ai2,ai3, ...aik|gcd(ai1, ai2, ...
- Nginx/Apache日志分析脚本
1,查看apache进程: ps aux | grep httpd | grep -v grep | wc -l 2,查看80端口的tcp连接: netstat -tan | grep "E ...
- WPF使用第三方的字体(TTF文件)
一.准备好你要使用的字体文件,以TTF结尾的文件,然后复制到项目中,并设置Build Action(生成操作)为Resource(资源): 二.在App.xaml中或者你需要的地方添加资源的定义: & ...
- (转) MFC的入口点与消息循环,消息映射
博文分析的很不错,尤其是替换默认窗口过程的这块,本人觉得,所有的这些都可以参阅侯杰的<深入浅出MFC >. 来自:http://blog.csdn.net/sryan/article/de ...
- matlab 中保存某几个变量
save AOA.mat dingjiao RMSE%保存变量dingjiao,RMSE于AOA.mat clear all;%当删除所有数据之后 load AOA.mat%还可以读出这两个变量的数 ...
- 解决git Push时请求username和password,而不是ssh-key验证
转载自:https://blog.lowstz.org/posts/2011/11/23/why-git-push-require-username-password-github/ 之前开始用git ...
- Android 签名(6)编译时源码的签名
1,使用源码中的默认签名 在源码中编译一般都使用默认签名的,在某源码目录中用运行下面命令能看到签名命令. $ mm showcommands Android提供了签名的程序signapk.jar,用法 ...
- the field is sometimes used inside synchronized block and sometimes used without synchronization
http://stackoverflow.com/questions/28715625/is-it-safe-to-use-field-inside-and-outside-synchronized- ...