weblogic有一个很贴心的功能,允许把多个war应用共同依赖的jar包,打包一个单独的war,以libary方式部署,然后各应用在weblogic.xml里声明引用该libary即可,这样可大大减少打包后的war文件尺寸,可以加快部署的上传进度,对web server而言,这类共用jar包只加载一次,也节省资源。

但是jboss下想达到类似的功能就要复杂很多了,先来一个简单的示例:

一、基础篇

1.1 假如我们先开发了一个工具库,打包后生成的mylib.jar ,为了减少各种依赖项的干扰,这个工程不依赖任何其它第三方库,只有一个测试方法:

package yjmyzz.test;

public class TestUtils {

    public String sayHello(String msg) {
return "Hello ," + msg + " !";
}
}

1.2 再建一个spring mvc的web项目,为了简单起见,也只有一个空页面,啥功能也没有,pom.xml里引用刚才的mylib工程

 <dependency>
<groupId>yjmyzz</groupId>
<artifactId>mylib</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>

Controller里,调用mylib中的sayHello方法

@RequestMapping("/index")
public String index() {
TestUtils utils = new TestUtils();
System.out.println(utils.sayHello("hello"));
return "index";
}

然后打包,默认情况下mylib.jar会打进myweb项目的WEB-INF/lib下  

前面这些都是准备工作而已,不用太在意具体细节,下面才是正经开始.

现在我们要把这个mylib-1.0.jar给弄到jboss里,让它成为jboss的默认模块,最终目的是myweb.war的WEB-INF/lib目录下,不再需要这个jar。

1.3 折腾 jboss EAP

a. $JBOSS_HOME/modules 目录下,创建 mylib/main 目录,即要保证$JBOSS_HOME/modules/mylib/main目录存在

b. 把mylib-1.0.jar复制到$JBOSS_HOME/modules/mylib/main中

c. 在$JBOSS_HOME/modules/mylib/main中创建一个名为module.xml的文件,内容如下:

 <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="mylib">
<resources>
<resource-root path="mylib-1.0.jar" />
</resources>
</module>

注意:第2行中的name="xxx"这里的name一定要跟/modules/下的子目录名一致,如果子目录是多层结构,比如 /modules/mycompany/mylib/main,则这里的name应该是"mycompany.mylib"

1.4 应用新增加的module

module加好以后,myweb在启动时并不知道jboss新增了这个module,有3种方法可以处理:

a) 修改myweb.war中META-INF/MANIFEST.MF清单文件

Manifest-Version: 1.0
Dependencies: mylib
Built-By: jimmy
Build-Jdk: 1.7.0_79
Created-By: Apache Maven 3.3.3
Archiver-Version: Plexus Archiver

注意第2行, Dependencies: mylib 把这行加上后,就表示myweb.war在启动时,要依赖mylib这个module,如果我们自己开发的module不止一个,多个module之间要英文逗号隔开,比如:module1,module2

当然,这一行如果要人工手动添加,未免太不讲究,有maven-plugin可以帮我们搞定:

 <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>mylib</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>

b) 还有第2种方式,在WEB-INF下添加文件jboss-deployment-structure.xml,内容如下:

 <jboss-deployment-structure>
<deployment>
<dependencies>
<module name="mylib"/>
</dependencies>
</deployment>
</jboss-deployment-structure>

c) 上面二种方式,都是由应用本身来控制加载哪些模块,也是我个人推荐的方式,还有一种一劳永逸的暴力方法,直接修改$JBOSS_HOME/standalone/configuration/standalone.xml文件(注:如果是domain模式,则相应修改domain.xml文件),内容如下:

 <subsystem xmlns="urn:jboss:domain:ee:1.1">
<global-modules>
<module name="mylib" slot="main"/>
</global-modules>
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
<jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
</subsystem>

根据关键字":ee:1.1"找到这段, 添加第2-4行即可,这样jboss在启动时,会把这个当成全局module,默认加载。

注:这种方式虽然简单,但是不推荐,原因是如果jboss部署了多个应用,其它应用不知道有这个全局module,在自己的项目中再重复打包这些jar包,极容易在启动时造成冲突,最终启动失败,各种报错。

只有一种情况,比较适合这种方式:数据库驱动jar,比如:ojdbc6.jar这类,不过对于数据库驱动jar包而言,有一种更简单的方式,直接将驱动jar包当成普通应用来部署就行了,所以这种改standalone.xml的方式,仍然体现不出优越性。

1.5 修改pom.xml ,不打包公用jar包

既然mylib这个公用jar已经移动jboss中了,那么myweb这个项目打包里就不必再打包它了,修改pom.xml中的相关部分:

 <dependency>
<groupId>yjmyzz</groupId>
<artifactId>mylib</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>

注意:第5行,改成provided表示该依赖项,运行时由jboss容器提供,因此打包时该项被忽略。

二、进阶篇

根据前面的步骤,好象并不难弄,但是实际应用中,如果想把一些知名的开源jar包,比如:spring, mybatis, hibernate , jackson这些全都以module的形式弄到jboss里,却并不容易,原因在于:这些开源项目本身又依赖其它开源项目,而其它开源项目,还有依赖,一层一层分析下来,关系十分复杂。更要命的的jboss本身也默认集成了一些知名的开源项目,比如:commons-logging之类,所以相互之间极容易冲突。就拿spring来说,最低层的是spring-core,它是依赖项最少的,如果要放到jboss的module中,module.xml内容为:

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

 <module xmlns="urn:jboss:module:1.1" name="mylib.spring-core">

     <resources>
<resource-root path="spring-core-4.1.1.RELEASE.jar" />
</resources> <dependencies>
<module name="org.apache.commons.logging"/>
<module name="javax.api" export="true"/>
<module name="org.jboss.vfs"/>
</dependencies> </module>

注意:9-13行,这里表示spring-core依赖了哪些更底层次的module,一个也都不能少,否则启动时就会有一堆其名其妙的错误。所以,分析众多开源项目和jboss内置module的依赖关系,将是一个极大的挑战。

spring 4.1.1-RELEASE整套jar包,全部以module方式融合进jboss的话,步骤如下:
a) modules目录下先创建子目录org/springframework/spring/main

b) 将spring的一堆jar包复制进来,文件列表如下:
spring-aop-4.1.1.RELEASE.jar               

spring-aspects-4.1.1.RELEASE.jar          

spring-beans-4.1.1.RELEASE.jar
spring-context-4.1.1.RELEASE.jar           

spring-context-support-4.1.1.RELEASE.jar   

spring-core-4.1.1.RELEASE.jar              

spring-expression-4.1.1.RELEASE.jar        

spring-instrument-4.1.1.RELEASE.jar        

spring-instrument-tomcat-4.1.1.RELEASE.jar
spring-jdbc-4.1.1.RELEASE.jar
spring-jms-4.1.1.RELEASE.jar
spring-messaging-4.1.1.RELEASE.jar
spring-orm-4.1.1.RELEASE.jar
spring-oxm-4.1.1.RELEASE.jar
spring-test-4.1.1.RELEASE.jar
spring-tx-4.1.1.RELEASE.jar
spring-web-4.1.1.RELEASE.jar
spring-webmvc-4.1.1.RELEASE.jar
spring-webmvc-portlet-4.1.1.RELEASE.jar
spring-websocket-4.1.1.RELEASE.jar

c) module.xml内容如下:

 <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.springframework.spring">
<resources>
<resource-root path="spring-aop-4.1.1.RELEASE.jar"/>
<resource-root path="spring-aspects-4.1.1.RELEASE.jar"/>
<resource-root path="spring-beans-4.1.1.RELEASE.jar"/>
<resource-root path="spring-context-4.1.1.RELEASE.jar"/>
<resource-root path="spring-context-support-4.1.1.RELEASE.jar"/>
<resource-root path="spring-core-4.1.1.RELEASE.jar"/>
<resource-root path="spring-expression-4.1.1.RELEASE.jar"/>
<resource-root path="spring-instrument-4.1.1.RELEASE.jar"/>
<resource-root path="spring-instrument-tomcat-4.1.1.RELEASE.jar"/>
<resource-root path="spring-jdbc-4.1.1.RELEASE.jar"/>
<resource-root path="spring-jms-4.1.1.RELEASE.jar"/>
<resource-root path="spring-messaging-4.1.1.RELEASE.jar"/>
<resource-root path="spring-orm-4.1.1.RELEASE.jar"/>
<resource-root path="spring-oxm-4.1.1.RELEASE.jar"/>
<resource-root path="spring-test-4.1.1.RELEASE.jar"/>
<resource-root path="spring-tx-4.1.1.RELEASE.jar"/>
<resource-root path="spring-web-4.1.1.RELEASE.jar"/>
<resource-root path="spring-webmvc-4.1.1.RELEASE.jar"/>
<resource-root path="spring-webmvc-portlet-4.1.1.RELEASE.jar"/>
<resource-root path="spring-websocket-4.1.1.RELEASE.jar"/>
</resources>
<dependencies>
<module name="org.apache.commons.logging"/>
<module name="javax.api" export="true"/>
<module name="javaee.api" export="true"/>
<module name="org.jboss.vfs"/>
</dependencies>
</module>%

d) 应用中jboss-deployment-structure.xml的内容如下:

 <?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.springframework.spring" export="true" meta-inf="export"/>
</dependencies>
</deployment>
</jboss-deployment-structure>

三、实战篇

下面就以一个Spring MVC 4.1.1 RELEASE + mybatis 3.2.8 + mysql + druid 的实例来说明,如何定制共享jar包:
这是打包后WEB-INF/lib下的所有依赖jar包:

aopalliance-1.0.jar
commons-dbcp-1.4.jar
commons-logging-1.1.3.jar
commons-pool-1.5.4.jar
mybatis-3.2.8.jar
mybatis-spring-1.2.2.jar
mysql-connector-java-5.1.25.jar
spring-aop-4.1.1.RELEASE.jar
spring-beans-4.1.1.RELEASE.jar
spring-context-4.1.1.RELEASE.jar
spring-core-4.1.1.RELEASE.jar
spring-expression-4.1.1.RELEASE.jar
spring-jdbc-4.1.1.RELEASE.jar
spring-tx-4.1.1.RELEASE.jar
spring-web-4.1.1.RELEASE.jar
spring-webmvc-4.1.1.RELEASE.jar

整个应用打包后,war包的尺寸约为6.7M(注:druid数据源是用在jboss创建jndi datasource的,所以不需要打包在war中)。根据前面的介绍,一步一步来精减发布包:

1. %JBOSS_HOME/modules/mylib/main 先创建该目录,把lib下的这些jar文件,全复制进去

2. 然后创建module.xml

 <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="mylib">
<resources>
<resource-root path="standard-1.1.2.jar"/>
<resource-root path="jstl-1.2.jar"/>
<resource-root path="aopalliance-1.0.jar"/>
<resource-root path="mybatis-3.2.8.jar"/>
<resource-root path="mybatis-spring-1.2.2.jar"/>
<resource-root path="mysql-connector-java-5.1.25.jar"/>
<resource-root path="spring-aop-4.1.1.RELEASE.jar"/>
<resource-root path="spring-beans-4.1.1.RELEASE.jar"/>
<resource-root path="spring-context-4.1.1.RELEASE.jar"/>
<resource-root path="spring-core-4.1.1.RELEASE.jar"/>
<resource-root path="spring-expression-4.1.1.RELEASE.jar"/>
<resource-root path="spring-jdbc-4.1.1.RELEASE.jar"/>
<resource-root path="spring-tx-4.1.1.RELEASE.jar"/>
<resource-root path="spring-web-4.1.1.RELEASE.jar"/>
<resource-root path="spring-webmvc-4.1.1.RELEASE.jar"/>
<resource-root path="druid-1.0.15.jar"/>
</resources>
<dependencies>
<module name="org.apache.commons.logging"/>
<module name="javax.api" export="true"/>
<module name="javaee.api" export="true"/>
<module name="javax.transaction.api" export="true"/>
<module name="javax.servlet.api" optional="true"/>
<module name="org.jboss.vfs"/>
</dependencies>
</module>

3. 应用中的jboss-deployment-structure.xml

 <?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclusions> </exclusions>
<dependencies>
<module name="mylib"/>
</dependencies>
</deployment>
</jboss-deployment-structure>

4. META-INF的特殊处理

因为spring的相关jar全放到jboss中了,这样会给应用本身运行带来问题,spring程序在启动时,会解析bean.xml配置文件,这个过程会加载spring.handers等文件,原来spring打包在应用本身中时,这些文件内嵌在sping的jar中,所以不会有问题,现在这些文件没有了,解析过程就会报错,因此需要手动把这些文件放到META-INF下,如图:

图中的这些文件,在spring里都可以找到,如果你的应用还使用了struts2,jstl,standard这些jar包,这些jar包里META-INF下的tld等文件也要复制到自己项目的META-INF下,根据我实际测试的结果,如果出现问题

spring-webmvc-xxx.jar

struts2-core-xxx.jar

这二个jar最好还是打包到应用中

最后别忘记了修改pom.xml文件,把所有依赖项的scope改成provided。

这样处理后,war包的尺寸从6.7M直接降到19K。

如何让jboss eap 6.2+ 的多个war应用共享 jar 包?的更多相关文章

  1. Jboss EAP:native management API学习

    上一节已经学习了CLI命令行来控制JBOSS,如果想在程序中以编码方式来控制JBOSS,可以参考下面的代码,实际上在前面的文章,用代码控制Jboss上的DataSource,已经有所接触了,API与C ...

  2. jboss eap 6.2+ 版本中 加密datasource密码等敏感信息

    默认情况下,在jboss eap 6.2+ 管理控制台创建datasource后,会在standalone.xml(独立模式)或host.xml(域模式)中以明文保存相关敏感信息. 这会给服务器留下安 ...

  3. Oracle Coherence应用部署到Jboss EAP 6.x 时 NoClassDefFoundError: sun/rmi/server/MarshalOutputStream 的解决办法

    今天将一个web应用从weblogic 10.3迁移到jboss EAP 6.3上,该应用使用oracle coherence做为缓存,部署上去后,启动时一直报如下错误:     at java.ut ...

  4. jboss eap 6.3 集群(cluster)配置

    接上一篇继续,Domain模式解决了统一管理多台jboss的问题,今天我们来学习如何利用mod_cluster来实现负载均衡.容错. mod_cluster是jboss的一个开源集群模块(基于apac ...

  5. jboss eap 6.3 域(Domain)模式配置

    jboss提供了二种运行模式:standalone(独立运行模式).domain(域模式),日常开发中,使用standalone模式足已:但生产部署时,一个app,往往是部署在jboss集群环境中的, ...

  6. 需要安全认证的远程EJB调用示例(Jboss EAP 6.2环境)

    一,Remote EJB 服务接口定义: package yjmyzz.ejb.server.helloworld; public interface HelloWorldService { publ ...

  7. jboss EAP 6.2 + Message Drive Bean(MDB) 整合IBM Webshpere MQ 7.5

    上一篇我们知道了消息驱动Bean的基本用法,实际大型分布式企业应用中,往往会采用高性能的商业Queue产品,比如IBM Webshpere MQ(目前最新版本是7.5 ),下面讲解下如何在Jboss ...

  8. JMS + jboss EAP 6.2 示例

    .Net中如果需要消息队列功能,可以很方便的使用微软自带的MSMQ,对应到Java中,这个功能就是JMS(Java Message Service). 下面以Jboss EAP 6.2环境,介绍一下基 ...

  9. vmware安装cent os 6.5 + oracle 11g xe + jboss eap 6.2 + weblogic 12c+ webshpere mq 7.5

    前言: mac系统发展速度确实很快,短短数年,mac os上已经能网银支付(中行.招行.工商.支付宝等均已全面支持mac os了),windows上的经典常用软件:qq.飞信.旺旺.有道词典.有道云笔 ...

随机推荐

  1. Linux Shell 网络层监控脚本(监控包括:连接数、句柄数及根据监控反馈结果分析)

    脚本监控: 获取最大句柄数的进程: 链接分析: 脚本片段: case "$handle" in 2) echo "The handle of the process : ...

  2. 验证位置时发生错误:“org.tigris.subversion.javahl.ClientException......

    验证位置时发生错 误:“org.tigris.subversion.javahl.ClientException: RA layer request failed svn: Server sent u ...

  3. 十五天精通WCF——第九天 高级玩法之自定义Behavior

    终于我又看完了二期爱情保卫战,太酸爽了,推荐链接:http://www.iqiyi.com/a_19rrgublqh.html?vfm=2008_aldbd,不多说,谁看谁入迷,下面言归正传, 看看这 ...

  4. 如何从SharePoint Content DB中查询List数据

    SharePoint用来维护基础数据非常方便,只需要建立自定义列表,然后使用InfoPath自定义一下维护界面,就可以实现在线的增删改查,开发效率很高.如果维护的数据需要进行审批,还可以加入工作流功能 ...

  5. LeetCode#227.Basic Calculator II

    题目 Implement a basic calculator to evaluate a simple expression string. The expression string contai ...

  6. x01.os.15: 看上去很美

    张碧晨在韩国学的不是技巧,而是基本功:气息!声音由气息托着,似真声而不是真声,似假声又不是假声,所以才能在动听的地方唱得更动听.编程也是一样,基本功很重要:内存!所谓的黑客高手,攻击的一大手段,便是利 ...

  7. 描述Linux shell中单引号,双引号及不加引号的简单区别(计时2分钟)

    简要总结: 单引号: 可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么. 双引号: 把双引号内的内容输出出来:如果内容中有命令.变量等,会先把变量.命令解析 ...

  8. 异常处理try-catch-finally

    php5.5新增 Finally模块 try {    //好好干,出了问题不要怕,外面有人接应} catch (HttpException $e) {    //时刻准备着,处理上面抛出的HTTP问 ...

  9. Java 代码的基本知识(摘)

    (摘自:Java经典入门教程) http://wenku.baidu.com/link?url=IoWI58cD5vzeHN-NL4pN7Gren-RfzydrhjDlETAByC9L-9ANinyL ...

  10. MySQL事务学习-->隔离级别

    MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...