码迷,mamicode.com
首页 > 其他好文 > 详细

Jboss5.1类加载及配置文件读取解密

时间:2016-05-12 23:29:28      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:

一般web项目部署在jboss的deploy目录下,其依赖的jar一般在web-inf\lib 里面(以下称warlib),但jboss还提供了一个lib文件即和deploy平行的目录(以下称defaultlib),这里面也可以放jar,按照网上的说法当war里需要的类在自身目录里找不到时就会去defaultlib里面去找(但实际项目中发现并非总是如此,例如涉及xml解析和spring的一些东西的时候)。

那么问题来了,当需要读取配置文件时到底读的哪儿的配置文件呢?总的来说配置文件有以下几个地方

在war的classes里

在war里lib文件夹里

在war的jar里

在defaultlib文件夹下

在defaultlib的jar里

对于上面涉及到jar的情况又分为在自己的jar里和在其他jar里两种情况,于是我写了下面的代码做测试


public class DefaultJar {
	public void print() throws IOException{
		System.out.println("-----"+this.getClass().getName()+"-----");
		ClassLoader parentLoader=null;
		ClassLoader threadLoader=Thread.currentThread().getContextClassLoader();
		System.out.println("ThreadLoader:"+threadLoader);
		parentLoader=threadLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		ClassLoader classLoader=this.getClass().getClassLoader();
		System.out.println(" ClassLoader:"+this.getClass().getClassLoader());
		parentLoader=classLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		System.out.println("     isEqual:"+(threadLoader==classLoader));
		InputStream is=null;
		byte[] data=null;
		is=threadLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from ThreadLoader:"+new String(data));
		is.close();
		is=classLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from  ClassLoader:"+new String(data));
		is.close();
		System.out.println();
	}
}

以上会打包成一个jar并放在defaultlib里,并且在jar里还有一个名字是classLoader的文件,里面写着“defaultjar”,另外在defaultlib里还有一个classLoader文件未被打入jar里,写的是outofjar

public class WarJar {
	public void print() throws IOException{
		System.out.println("-----"+this.getClass().getName()+"-----");
		ClassLoader parentLoader=null;
		ClassLoader threadLoader=Thread.currentThread().getContextClassLoader();
		System.out.println("ThreadLoader:"+threadLoader);
		parentLoader=threadLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		ClassLoader classLoader=this.getClass().getClassLoader();
		System.out.println(" ClassLoader:"+this.getClass().getClassLoader());
		parentLoader=classLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		System.out.println("     isEqual:"+(threadLoader==classLoader));
		InputStream is=null;
		byte[] data=null;
		is=threadLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from ThreadLoader:"+new String(data));
		is.close();
		is=classLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from  ClassLoader:"+new String(data));
		is.close();
		System.out.println();
	}
}

以上打成一个jar放在warlib里,同样在jar里还有个classLoader的配置文件,里面写着“warjar”

还有一个web项目

public class WarClass {
	public void print() throws IOException{
		System.out.println("-----"+this.getClass().getName()+"-----");
		ClassLoader parentLoader=null;
		ClassLoader threadLoader=Thread.currentThread().getContextClassLoader();
		System.out.println("ThreadLoader:"+threadLoader);
		parentLoader=threadLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		ClassLoader classLoader=this.getClass().getClassLoader();
		System.out.println(" ClassLoader:"+this.getClass().getClassLoader());
		parentLoader=classLoader;
		do{
			parentLoader=parentLoader.getParent();
			System.out.println("\tParentLoader:"+parentLoader);
		}while(null!=parentLoader);
		System.out.println("     isEqual:"+(threadLoader==classLoader));
		InputStream is=null;
		byte[] data=null;
		is=threadLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from ThreadLoader:"+new String(data));
		is.close();
		is=classLoader.getResourceAsStream("classLoader");
		data=new byte[is.available()];
		is.read(data);
		System.out.println("data from  ClassLoader:"+new String(data));
		is.close();
		System.out.println();
	}
}

在这个web项目里还有个初始化时就启动的servlet如下

public class InitServlet extends HttpServlet {

	@Override
	public void init() throws ServletException {
		super.init();
		try {
			new WarClass().print();
			new WarJar().print();
			new DefaultJar().print();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
同样在war里也有配置文件,写的是“warclass”

注意以上三个不在同一个package里

放入jboss执行后运行结果:

2016-05-05 14:06:35,884 INFO  [STDOUT] (main) -----com.warclass.WarClass-----
2016-05-05 14:06:35,884 INFO  [STDOUT] (main) ThreadLoader:org.jboss.web.tomcat.service.WebCtxLoader$ENCLoader@171fe0d
2016-05-05 14:06:35,884 INFO  [STDOUT] (main) ParentLoader:BaseClassLoader@1cf0283{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/deploy/WarClass.war/}
2016-05-05 14:06:35,884 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,884 INFO  [STDOUT] (main)  ClassLoader:BaseClassLoader@1cf0283{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/deploy/WarClass.war/}
2016-05-05 14:06:35,884 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,884 INFO  [STDOUT] (main)      isEqual:false
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from ThreadLoader:warclass
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from  ClassLoader:warclass
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) -----qbit.warjar.WarJar-----
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ThreadLoader:org.jboss.web.tomcat.service.WebCtxLoader$ENCLoader@171fe0d
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:BaseClassLoader@1cf0283{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/deploy/WarClass.war/}
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,899 INFO  [STDOUT] (main)  ClassLoader:BaseClassLoader@1cf0283{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/deploy/WarClass.war/}
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,899 INFO  [STDOUT] (main)      isEqual:false
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from ThreadLoader:warclass
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from  ClassLoader:warclass
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) -----qbit.defaultjar.DefaultJar-----
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ThreadLoader:org.jboss.web.tomcat.service.WebCtxLoader$ENCLoader@171fe0d
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:BaseClassLoader@1cf0283{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/deploy/WarClass.war/}
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,899 INFO  [STDOUT] (main)  ClassLoader:BaseClassLoader@34600d{vfsfile:/D:/PowerNT5Server/jboss-5.1.0.GA/server/default/conf/jboss-service.xml}
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) ParentLoader:null
2016-05-05 14:06:35,899 INFO  [STDOUT] (main)      isEqual:false
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from ThreadLoader:warclass
2016-05-05 14:06:35,899 INFO  [STDOUT] (main) data from  ClassLoader:defaultjar


从结果来看:

war和defaultlib里面的class用的是两个classLoader

thread都是同一个classLoader,这个容易想到,但是意外的发现他的classLoader居然是war里的classLoader

至于两个classLoader读取配置文件,war的读取的是classes下面,而defaultlib里面读取的是jar里面另外根据其他的实验表名读取配置名字是读取名字最小的jar里(那就说明未必和读取配置文件代码所在的jar是同一个jar)


Jboss5.1类加载及配置文件读取解密

标签:

原文地址:http://blog.csdn.net/kamputer/article/details/51348200

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!