Jboss7类加载器

1. 类加载器理论知识介绍

类加载器基于Jboss Module,取代了层次类加载环境,避免了当类存在多个版本时,导致类加载错误。

类加载是基于模块的,必须显示的定义模块依赖。部署也是模块化的,如果没有显示的定义类依赖则不能访问应用服务器jar中的类。在部署过程中,一些由应用服务器定义的模块依赖会自动装配。例如,如果部署一个Java EE 应用,将自动添加Java EE API依赖,这也成为隐式模块依赖。对于其他的类,必须在MANIFEST.MF文件的”Dependencies:”或”Class-Path:”项,或在jboss-deployment-structure.xml文件中定义显示的模块依赖。

类加载优先级(从高到低):

1.  系统依赖– 容易自动将加载的模块依赖,包括Java EE API

2. 用户依赖– 在jboss-deployment-structure.xml(ear的META-INF内,war的META-INF或WEB-INF内)或Dependencies:项内配置的依赖。

3. 本地资源– 发布目录下的类文件,如war包下的WEB-INF/classes或WEB-INF/lib

4. 部署间依赖– 在ear内的其他部署依赖。包括ear lib目录内的类,或其他ejb内的了;类。

War被认为一个单独的模块,WEB-INF/lib或WEB-INF/classes内的类是相同的,都由同一类加载器加载

2. 下面使用具体的例子展示一下类加载器的优先级

环境:Eclipse+Maven+Jboss 6.2 EAP

1.      创建Maven项目分别是:itoo-pangfan-web itoo-pangfan-core itoo-pangfan-ear

注意在创建maven项目过程中packaging分别是war jar ear

2.      配置pom.xml文件如下

itoo-pangfan-core的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tgb</groupId>
  <artifactId>itoo-pangfan-core</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</project>

itoo-pangfan-ear的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.tgb</groupId>
	<artifactId>itoo-pangfan-ear</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>ear</packaging>

	<dependencies>
		<dependency>
			<groupId>com.tgb</groupId>
            <artifactId>itoo-pangfan-core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>ejb</type>
		</dependency>
		<dependency>
			<groupId>com.tgb</groupId>
            <artifactId>itoo-pangfan-web</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>war</type>
		</dependency>
	</dependencies>

</project>

itoo-pangfan-web的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.tgb</groupId>
	<artifactId>itoo-pangfan-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.0.8.RELEASE</version>
		</dependency>
	</dependencies>
</project>

3.      配置spring-mvc.xml文件

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
">

	<bean name="myController" class="com.tgb.itoo.basic.controller.MyController">
	</bean>

	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

	<mvc:annotation-driven />

	<mvc:resources location="/demo/" mapping="/demo/**"></mvc:resources>
	<mvc:resources location="/themes/" mapping="/themes/**"></mvc:resources>
	<mvc:resources location="/locale/" mapping="/locale/**"></mvc:resources>
	<mvc:resources location="/" mapping="/**"></mvc:resources>
</beans>

4.      创建MyController

MyController

package com.tgb.itoo.basic.controller;
import java.util.HashSet;
import java.util.Set;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.google.gson.Gson;

@Controller
public class MyController {
	@RequestMapping("/index")
	public String index() {
		Gson gson = new Gson();
		User user1 = new User(); //创建User对象(User类的代码省略,自己创建)
		user1.setId(1);
		user1.setName("xxx");
		User user2 = new User();
		user2.setId(2);
		user2.setName("xxx");
		Set<User> users = new HashSet<User>();
		users.add(user1);
		users.add(user2);
        <span style="white-space:pre">	</span>// 带泛型的list转化为json
        <span style="white-space:pre">	</span>String s = gson.toJson(users);
        <span style="white-space:pre">	</span>System.out.println(s);  //打印转换之后的json串
		return "index";
	}
}

使用gson转换Json串,所以在web的pom.xml文件中引入此jar

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.3.1</version>
		</dependency>

5.      部署测试

测试一:部署执行

部署成功后访问:http://localhost:8080/itoo-pangfan-web/index

分析:

1.      系统依赖 - 这是一个Jave EE项目,在Jboss部署过程中会自动加载Java EEAPI的相关依赖

2.      用户依赖– 无

3.      本地资源– war包中的WEB-INF/classes和WEB-INF/lib(maven依赖的jar)

4.      部署间依赖– itoo-pangfan-core(jar)和itoo-pangfan-web(war)

部署成功说明gson的jar是从本地资源中读取

测试二:在gson的依赖中加入<scope>provided</scope>

provided:打包时不用此依赖。也就是说在打包完成之后google不会出现在WEB-INF/lib中。

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.3.1</version>
			<scope>provided</scope>
		</dependency>

再部署运行报错,提示gson找不到

JBWEB000236: Servlet.service() for servlet action threw exception: java.lang.ClassNotFoundException: com.google.gson.Gson from [Module "deployment.itoo-pangfan-ear.ear.itoo-pangfan-web-0.0.1-SNAPSHOT.war:main" from Service Module
Loader]

依据我们上面分析的情况,gson只存在在本地资源中,因为本地资源找不到所以报错。

那么如果解决呢?对,放到用户依赖中。

1.      创建jboss-deployment-structure.xml

将jboss-deployment-structure.xml在ear的META-INF内,war的META-INF或WEB-INF任意一个位置。在这里我放到ear中,文件的内容如下

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
	<sub-deployment name="itoo-pangfan-web-0.0.1-SNAPSHOT.war">
		<dependencies>
			<module name="org.jboss.xnio" />
			<module name="com.google.code.gson">
				<imports>
					<include path="META-INF**" />
					<include path="org**" />
				</imports>
			</module>
		</dependencies>
	</sub-deployment>
</jboss-deployment-structure>

2.      配置Jboss Module

jboss根目录下面原来的modules里面com文件夹,内部包括gson.jar和main文件。com文件的目录结构如下:

module.xml

<module xmlns="urn:jboss:module:1.0" name="com.google.code.gson">
    <resources>
        <resource-root path="gson-2.3.1.jar"/>
    </resources>
</module>

3.      部署测试

现在就将gson放到了用户依赖这一级,重新部署运行(注意Jboss也要重新启动)

6. 总结

对于我们来讲操作比较多的是用户依赖,本地资源以及部署间依赖。上面的例子主要是讲解了用户依赖和本地资源之间的级别。如果用户依赖和本地资源同时拥有gson,jar,也是会读取用户资源中的jar。

从上面可以看出如果不使用用户依赖,我们的程序部署也是没有问题的,那么为什么还要用户用户依赖呢?

1. jar重复利用

2. 减少单个项目的体积,提高性能

如果gson作为本地资源存在,那么我们就必须要将它打包到war中;如果gson存在在jboss modules中,war就不用存在gson了,那么一个ear的体积就能够减少。除此之外,gson也能够被其他部署在服务器中的ear使用。这里也是体现一个分层的思想,在开发中将公共的jar包,使用频率比较高的jar同一个放到jboss中,那么当我们使用的时候只要配置一下就可以了,不用再添加打包到每一个ear中,是我们提升性能一个比较重要的方面。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 03:39:08

Jboss7类加载器的相关文章

自定义一个类加载器

http://www.cnblogs.com/xrq730/p/4847337.html 为什么要自定义类加载器 类加载机制:http://www.cnblogs.com/xrq730/p/4844915.html 类加载器:http://www.cnblogs.com/xrq730/p/4845144.html 这两篇文章已经详细讲解了类加载机制和类加载器,还剩最后一个问题没有讲解,就是 自定义类加载器.为什么我们要自定义类加载器?因为虽然Java中给用户提供了很多类加载器,但是和实际使用比起

自定义类加载器——加载任意指定目录的class文件

public class MyClassLoader extends ClassLoader{ String path;//自定义类加载器所负责的文件夹 public MyClassLoader(String path) { super(); this.path = path; } @SuppressWarnings("deprecation") @Override protected Class<?> findClass(String name) throws Class

Java类加载器的工作原理

Java类加载器的作用就是在运行时加载类.Java类加载器基于三个机制:委托.可见性和单一性.委托机制是指将加载一个类的请求交给父类加载 器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它.可见性的原理是子类的加载器可以看见所有的父类加载器加载的类,而父类加载器看不到子类 加载器加载的类.单一性原理是指仅加载一个类一次,这是由委托机制确保子类加载器不会再次加载父类加载器加载过的类.正确理解类加载器能够帮你解决 NoClassDefFoundError和java.lang.ClassNo

[email&#160;protected]动态代理-类加载器

一.测试单元     概述:用于测试JAVA代码的工具类,已内置在Eclipse中;     格式:         1.在方法的上面添加@Test;         2.对被测试的方法的要求:权限-public;返回值-void;参数-空参         [email protected]:在@Test标注的方法前执行,可以用于初始化;           @After:在@Test标注的方法后执行,可以用于释放资源; 二.注解     概述:java的一种数据类型,和类/接口在同一级别  

jvm学习二:类加载器

前一节详细的聊了一下类的加载过程,本节聊一聊类的加载工具,类加载器  ---  ClassLoader 本想自己写的,查资料的时候查到一篇大神的文章,写的十分详细 大家直接过去看吧http://blog.csdn.net/zhoudaxia/article/details/35824249

Java基础知识之类加载器

1.类加载器定义 1.1类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制.JVM中用来完成上述功能的具体实现就是类加载器.类加载器读取.class字节码文件将其转换成java.lang.Class类的一个实例.每个实例用来表示一个java类.通过该实例的newInstance()方法可以创建出一个该类的对象. 1.2类的生命周期: 类从加载到虚拟

Java重要技术(28)类加载器之类加载器的层次关系和委托加载机制

1.1. 类加载器的层次 类加载器包括三种: Bootstrap ClassLoader:用于加载JRE的lib目录下的jar文件中的class. ExtClassLoader:用于加载JRE的lib/ext目录下的jar文件中的class. AppClassLoader:用于加载classpath下的class. 在加载一个class时,通常应该先委托给parent类加载器来加载,parent类加载器找不到这个类时,才自行加载.实际优先次序从高到低排列是BootStrap ClassLoade

Java重要技术(29)类加载器之类加载器的职责

1.1. 类加载器的职责 每个类(Class)都有一个类加载器.类加载器ClassLoader的职责包括以下内容: (1)类的定位.根据类的名称找到对应的class文件,也可以不需要class文件. (2)类的定义.产生表达类的定义的Class类的实例. 某个Sample类的代码如下: package com.test.javatechnology.classloader.test; //Sample类的class文件将位于test目录下. public class Sample { //NOT

Java中的类加载器

转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制 我们知道,Java是一种动态语言.那么怎样理解这个"动态"呢?或者说一门语言具备了什么特性,才能称之为动态语言呢?对于java,我是这样理解的. 我们都知道JVM(java虚拟机)执行的不是本地机器码指令,而是执行一种称之为字节码的指令(存在于class文件中).这就要求虚拟机在真正执行字节码之前,先把相关的class文件加载到内存