【IT168 技术文章】
本文介绍了将 J2EE 应用程序从不同平台移植到 WebSphere 应用服务器上的共同方法和常见的问题.
概述
Apache Cocoon是Apache开放源码组织Jakarta项目中的一个重要的子项目,其目标是用最少的编码实现基于XML的Web开发框架(使用XML和XSLT)。Cocoon可以方便地生成PDF文件、XLS电子表格或者动态网页而不需要编写大量的代码,它是一个J2EE应用程序,可以部署在任何J2EE应用服务器的Web 容器中。然而,WebSphere Studio Application Developer并没有像支持struts那样提供对Cocoon的内嵌支持,所以,如果要在WebSphere中部署Cocoon框架,我们需要作少量的配置。
本文假定您熟悉Cocoon框架,并且使用WebSphere Studio Application Developer(WSAD)开发过部署在WebSphere应用服务器上的J2EE应用程序。
下面我们将详细描述在WSAD中部署Cocoon框架所遇到的问题和解决方案。
注意:这篇文章是针对WebSphere应用服务器5.0.2版本和WSAD 5.1版本,使用的Cocoon框架是2.0和2.1版本。
在WSAD中部署Cocoon的步骤
1、下载Cocoon的源文件包
2、解压缩源文件包,使用源文件包中提供的build命令构建Cocoon.war
3、将Cocoon.war导入到WSAD当中
4、创建WebSphere V5.0 测试环境
5、排除部署的问题,运行Cocoon框架中的hello-world样本进行验证
部署问题及其解决方案
问题一:在启动WebSphere应用服务器时,某些Cocoon相关的类无法被正确的装载,致使整个Cocoon应用程序无法正确初始化。
问题分析:这个问题和WebSphere的类装入器方式(class loading mode)有关。WebSphere的类装入器方式有两种方式:PARENT_FIRST和PARENT_LAST。默认值是PARENT_FIRST,这种方式在载入当前classpath的类之前先载入其上一级classloader能够装入的类。这是标准的JVM classloader的默认策略。如果采用PARENT_LAST,则过程正好相反,即先载入当前classpath的类,再载入其上一级classloader能够装入的类,这样可以用当前classpath中更新的类覆盖其上一级classloader的相同类。受类装入器方式影响的classloader包括application classloader、WAR classloader以及共享类库的classloader。
解决方案:由于Cocoon所用的Xalan和Xerces版本和WebSphere不同,所以需要将Cocoon应用程序的"类装入器方式"设置为"PARENT_LAST", 这样WebSphere应用服务器会先从Cocoon应用程序中的JAR文件查找类。具体设置步骤如下:
1、 在WSAD中打开服务器配置编辑器
2、 选择"应用程序"标签
3、 选择Cocoon应用程序,将"类装入器方式"设置为"PARENT_LAST",如图一所示:
图一、设置应用程序的类装入器方式
4、 选择Cocoon应用程序的Web模块,将"类装入器方式"设置为"PARENT_LAST",如图二所示:
图二、设置Web模块的类装入器方式
注意:步骤3和4必须都设置。
问题二:Web应用在启动时有时会报出配置错误的消息
问题分析:在Web部署描述符web.xml中,某些注释信息有可能会被WebSphere视作XML文件的内容,从而使得WebSphere应用服务器在启动时读入了错误的配置信息。
解决方案:删除web.xml文件中掺杂在
问题三: Cocoon框架中的sitemap规范中的某些功能无法生效,例如:
2 <map:redirect-to uri="index.html" />
解决方案:对于Cocoon 2.0.4和2.1,我们应当做如下的修改:
2 <map:redirect-to uri="{request:contextPath}/documents/index.html"/>
问题四:在WebSphere测试环境中,在使用通用日志(commons logging)功能时经常会抛出如下的异常:
org.apache.commons.logging.LogConfigurationException:
java.lang.ClassCastException: com.ibm.ws.commons.logging.TrLogFactory
at org.apache.commons.logging.LogFactory$2.run(LogFactory.java:609)
at java.security.AccessController.doPrivileged(Native Method)
at
org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:561)
at
org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:352)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:395)
at
biz.deltafaucet.contacts_list.ContactsListPortlet.
ortlet.java:45)
at java.lang.Class.newInstance0(Native Method)
at java.lang.Class.newInstance(Class.java(Compiled Code))
at java.beans.Beans.instantiate(Beans.java:233)
问题分析:在WSAD中有一个默认的IBM日志工厂(log factory)实现类com.ibm.ws.commons.logging.TrLogFactory。如果应用程序中使用的是Apache组织开发的实现类就会出现这样的错误。
解决方案:有两个解决办法:其一是将应用程序的类装入器方式(class loading mode)设为PARENT_LAST。另一种办法是在WebSphere的系统参数中添加如下系统属性,如图三所示:
org.apache.commons.logging.LogFactory =
org.apache.commons.logging.impl.LogFactoryImpl
图三、添加WebSphere系统属性
问题五:在访问Cocoon应用程序时经常会抛出如下的异常:
java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available
at java.security.Security.getAlgClassName(Security.java:576)
at java.security.Security.getAlgClassName(Security.java:598)
at java.security.Security.getImpl(Security.java:1079)
at java.security.SecureRandom.getInstance(SecureRandom.java:241)
at org.apache.Cocoon.components.flow.ContinuationsManagerImpl.
......
问题分析:由于WebSphere应用服务器5.0.2版本所使用的IBM SDK不包含对SHA1PRNG算法的支持,所以会有上述错误发生。
解决方案:需要对 /src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java进行修改,用IBMSecureRandom算法替换SHA1PRNG算法:
2
3 random = SecureRandom.getInstance("SHA1PRNG");
4
5 try {
6
7 random = SecureRandom.getInstance("SHA1PRNG");
8
9 }
10
11 catch(java.security.NoSuchAlgorithmException nsae) {
12
13 // maybe we are on IBM's SDK
14
15 random = SecureRandom.getInstance("IBMSecureRandom");
16
17 }
18
19 random.setSeed(System.currentTimeMillis());
20
21 bytes = new byte[CONTINUATION_ID_LENGTH];
22
23 }
24
25
然后重新编译ContinuationsManagerImpl.java,并将其类文件替换Cocoon的jar包中原来的文件即可。除了以上的问题,Cocoon框架自身可能会存在一些bug。所以如果有问题可以查看 http://cvs.apache.org/上的Cocoon的更新,以获得更佳稳定的Cocoon框架。以上是在WebSphere应用服务器5.0.2版本上部署Cocoon框架2.0和2.1版本的主要问题。