在《WebSphere Classloader对应用移植的影响(一)》中,我们简单介绍了在移植的前期的工作,西安免我们将具体以一个实例来进行讲解。
实例
接下来,我们用一个实例来说明针对特定的模块依赖关系应当如何设置WebSphere Classloader的装载策略(policy)以及如何将各个模块部署到合适的位置。
有一个应用程序里有三个互相依赖的模块,其调用关系如下:
图二、模块关系图
其中,WAR模块中的SampleServlet类调用了UTILITY模块中SampleUtility类,如代码一所示:
代码一、SampleServlet.java
以下是引用片段: 1 public class SampleSevlet extends HttpServlet implements Servlet { 2 3 public void doGet(HttpServletRequest req, HttpServletResponse resp) 4 5 throws ServletException, IOException { 6 7 System.out.println(“SampleServlet invokes SampleUtility”); 8 9 new SampleUtility().callSampleSessionBean(); 10 11 } 12 13 public void doPost(HttpServletRequest req, HttpServletResponse resp) 14 15 throws ServletException, IOException { 16 17 } 18 19 } |
UTILITY模块中SampleUtility类调用了EJB模块中的SampleSessionBean类(通过callSampleSessionBean方法),如代码二所示:
代码二、SampleUtility.java
以下是引用片段: 1 public class SampleUtility { 2 3 public void callSampleSessionBean() { 4 5 try{ 6 7 Context initCtx = new InitialContext(); 8 9 Object result = initCtx.lookup(“ejb/sample/SampleSessionHome”); 10 11 SampleSessionHome ssh = (SampleSessionHome) 12 13 PortableRemoteObject.narrow( 14 15 result, SampleSessionHome.class); 16 17 SampleSession ss = ssh.create(); 18 19 System.out.println(“SampleUtility invokes SampleSessionBean”); 20 21 ss.callSampleUtility(); 22 23 }catch(Exception e){ 24 25 e.printStackTrace(); 26 27 } 28 29 } 30 31 public void finish() { 32 33 System.out.println(“The process has been finished”); 34 35 } 36 37 } |
SampleSessionBean类又调用了UTILITY模块中的SampleUtility类,如代码三所示:
代码三、SampleSessionBean.java
以下是引用片段: 1 public class SampleSessionBean implements javax.ejb.SessionBean { 2 3 private javax.ejb.SessionContext mySessionCtx; 4 5 public javax.ejb.SessionContext getSessionContext() { 6 7 return mySessionCtx; 8 9 } 10 11 public void setSessionContext(javax.ejb.SessionContext ctx) { 12 13 mySessionCtx = ctx; 14 15 } 16 17 public void ejbCreate() throws javax.ejb.CreateException { 18 19 } 20 21 public void ejbActivate() { 22 23 } 24 25 public void ejbPassivate() { 26 27 } 28 29 public void ejbRemove() { 30 31 } 32 33 public void callSampleUtility() { 34 35 System.out.println(“SampleSessionBean invokes SampleUtility”); 36 37 new SampleUtility().finish(); 38 39 } 40 41 } |
这三个类之间的调用关系如下图所示:
图三、顺序图
下面我们通过不同的部署策略来深入探讨WebSphere Classloader是如何影响应用程序运行的。1、如果将Utility模块(JAR文件)拷贝到Web 模块的 WEB-INF/lib 文件夹中,那么,Utility模块将会被视为War模块的一部分,如图所示:
图四、Utility模块(JAR文件)在Web模块中
如果我们将WAR Classloader Policy设置为MODULE(默认设置),如图五所示:
图五、WAR Classloader Policy设置
那么WebSphere应用服务器会使用WAR Classloader来装载WAR模块的类文件。而EJB模块始终是通过Application Classloader进行装载,由于Application Classloader处于WAR classloader的上层,EJB模块无法引用War模块的类文件。这样,当SampleSessionBean调用SampleUtility时,会抛出异常:
以下是引用片段: SystemOut O SampleServlet invokes SampleUtility SystemOut O SampleUtility invokes SampleSessionBean SystemOut O SampleSessionBean invokes SampleUtility |
ExceptionUtil E CNTR0020E: 在 bean”BeanId(Sample#SampleEJB.jar#SampleSession, null)”上处理方法”callSampleUtility”时发生非应用程序异常。异常数据:
以下是引用片段: java.lang.NoClassDefFoundError: sample/SampleUtility at sample.SampleSessionBean.callSampleUtility(SampleSessionBean.java:41) |
如果我们将WAR Classloader Policy设置为APPLICATION,那么WebSphere应用服务器会使用Application Classloader来装载WAR模块和EJB模块的类文件。由于两个模块使用了相同的Classloader进行装载,所以两个模块间的类可以相互引用应用服务器输出的结果如下:
以下是引用片段: SystemOut O SampleServlet invokes SampleUtility SystemOut O SampleUtility invokes SampleSessionBean SystemOut O SampleSessionBean invokes SampleUtility SystemOut O The process has been finished |
2、如果将Utility模块拷贝到%was_root%libext , Websphere应用服务器会使用WebSphere Extensions Classloader加载Utility模块中的类文件,由于WebSphere Extensions Classloader处于Application classloader和WAR classloader的上层,所以SampleServlet和SampleSessionBean可以引用到SampleUtility,但是SampleUtility引用不到SampleSessionBean,因此,当SampleUtility调用SampleSessionBean时会抛出异常。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
内存数据网格提供商一头扎进Java
10年的时间里,应用性能解决方案提供商Alachisoft一直在用NCache(针对N-Tier和网格计算.NET应用的内存计算和数据网格产品)为.NET社区服务。
-
遇到这样一个问题:通过java service wrapper部署应用,wrapper进程占用的内存会一直升高, 直到把内存吃完应用崩溃,但是这个wrapper
遇到这样一个问题:通过java service wrapper部署应用,wrapper进程占用的内存会一直升高 […]
-
Google App Engine for Java 对于目前中国需要学习吗?
-
前无古人后无来者的Java平台
开发人员一直在致力于保持Java的活力,经过20年后,我们感觉从来没有更好的、更令人激动的时刻如同Java社区一样。