接下来,我们用一个实例来说明针对特定的模块依赖关系应当如何设置WebSphere Classloader的装载策略(policy)以及如何将各个模块部署到合适的位置。
有一个应用程序里有三个互相依赖的模块,其调用关系如下:
图二、模块关系图

其中,WAR模块中的SampleServlet类调用了UTILITY模块中SampleUtility类,如代码一所示:
代码一、SampleServlet.java
Code highlighting produced by Actipro CodeHighlighter (freeware)UTILITY模块中SampleUtility类调用了EJB模块中的SampleSessionBean类(通过callSampleSessionBean方法),如代码二所示:
代码二、SampleUtility.java
Code highlighting produced by Actipro CodeHighlighter (freeware)SampleSessionBean类又调用了UTILITY模块中的SampleUtility类,如代码三所示:
代码三、SampleSessionBean.java
Code highlighting produced by Actipro CodeHighlighter (freeware)这三个类之间的调用关系如下图所示:
图三、顺序图

下面我们通过不同的部署策略来深入探讨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%\lib\ext , Websphere应用服务器会使用WebSphere Extensions Classloader加载Utility模块中的类文件,由于WebSphere Extensions Classloader处于Application classloader和WAR classloader的上层,所以SampleServlet和SampleSessionBean可以引用到SampleUtility,但是SampleUtility引用不到SampleSessionBean,因此,当SampleUtility调用SampleSessionBean时会抛出异常。