最近几天研究Dozer的性能,需要改写Dozer 中的几个类但是又不打算重新编译Dozer的jar 包了, 所以偷懒在genidc-biz-service 工程的src 目录下创建在dozer jar 中相同名称的类包, 图中的"org.dozer", "org.dozer.cache", "org.dozer.converters", 拷贝dozer 源代码中的相关类过来, 然后在这里动手改。
发布的时候, 发现奇怪了, 程序还是在跑Dozer jar 包中的老代码, 我所新添加的代码都没跑到。 以前玩Tomcat的时候, 开源Jar 包下的类就这么干的, 工作好好的。 tomcat 的类文件优先加载级别是
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order: Bootstrap classes of your JVM System class loader classes (described above) /WEB-INF/classes of your web application /WEB-INF/lib/*.jar of your web application Common class loader classes (described above)
所以web 工程编译出来的class 文件是比lib 包下的jar 文件中的class 文件优先加载的。
恩,看来Jboss 下的类文件加载不是这么玩的。 咨询谷歌大神, 他告诉我需要以下步骤
1. 修改ear 下的jboss-application.xml, 做如下设置, 它的作用是告诉类加载器强制按照ear 包下的application.xml 中指定的jar 包顺序做加载。
<jboss-app> <module-order>strict</module-order> </jboss-app>
查看了我们的genidc-ear 工程, target 打出来的jboss-application.xml 已经是这样了,
2. 然后在application.xml 中设置加载顺序
<application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" version="1.4"> <display-name>genidc-ear</display-name> <module> <java>lib/genidc-common-service-3.1.jar</java> </module> <module> <java>lib/genidc-common-presentation-3.1.jar</java> </module> <module> <java>lib/genidc-biz-manager-3.1.jar</java> </module> <module> <java>lib/genidc-biz-model-3.1.jar</java> </module> <module> <java>lib/genidc-biz-service-3.1.jar</java> </module> <module> <java>lib/dozer-5.2.0.jar</java> </module> <module> <ejb>genidc-ejb3-3.1.jar</ejb> </module> </application>
这里,没有在这里指定的ear 中的其他jar 包, 默认的加载顺序是和这里的jar 包一起按照字母顺序加载, 如果不特别指定dozer加载顺序, 那么因为dozer jar 比genidc-biz-service-3.1.jar 字母序靠前, 所以dozer 中的MappingProcessor.class会先加载, 然后等到加载genidc-biz-service-3.1.jar 中的MappingProcessor.class, 类装载器认为已经加载过, 就跳过了加载。 所以这里只要强行指定这个dozer-5.2.0.jar 比genidc-biz-service-3.1.jar后加载就OK了。 把这个修改了的ear 包放Jboss里,跑起来对了。
3. 且慢, 光这样改还不行, 重新run 下maven, application.xml 又变回去了, 那么这些配置文件的生成肯定和Maven的脚本有关。查看genidc-ear 工程下的pom 有个maven-ear plugin 的配置, 原来, application.xml 中的jar 以及顺序都是它指定, 还有jboss-application.xml 中的module-order 也是这里指定的。 在这里加上dozer 的配置, OK, maven build 出来的application.xml 就是我们想要的了。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <version>2.3.1</version> <configuration> <displayName></displayName> <description></description> <version>1.4</version> <defaultLibBundleDir>lib</defaultLibBundleDir> <modules> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-utility</artifactId> <includeInApplicationXml>false</includeInApplicationXml> </jarModule> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-common-service</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-common-presentation</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-biz-manager</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-biz-model</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <jarModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-biz-service</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <jarModule> <groupId>net.sf.dozer</groupId> <artifactId>dozer</artifactId> <includeInApplicationXml>true</includeInApplicationXml> </jarModule> <ejbModule> <groupId>oasis.genidc</groupId> <artifactId>genidc-ejb3</artifactId> </ejbModule> </modules> <jboss> <version>4.2</version> <module-order>strict</module-order> </jboss> </configuration> </plugin>