级别: 初级 白钢 (baigang@cn.ibm.comm), 高级软件工程师 张羽 (zhangyyu@cn.ibm.com), 高级软件工程师
2004 年 8 月 01 日 本文介绍了将 J2EE 应用程序从不同平台移植到 WebSphere 应用服务器上的共同方法和常见的问题.
概述
Apache Cocoon(
http://cocoon.apache.org/index.html)是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、从
http://archive.apache.org/dist/Cocoon/上下载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文件中掺杂在<init-param><param-name>load-class</param-name></init-param>中的注释。
问题三: Cocoon框架中的sitemap规范中的某些功能无法生效,例如:
<map:match pattern="documents/index">
<map:redirect-to uri="index.html" />
问题分析:由于WebSphere应用服务器的5.0.2版本没有完全遵从Servlet 2.3规范,所以导致上述错误。
解决方案:对于Cocoon 2.0.4和2.1,我们应当做如下的修改:
<map:match pattern="document/index">
<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.<clinit>(ContactsListP
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.<init>(ContinuationsManagerImpl.java:119)
......
问题分析:由于WebSphere应用服务器5.0.2版本所使用的IBM SDK不包含对SHA1PRNG算法的支持,所以会有上述错误发生。
解决方案:需要对 /src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java进行修改,用IBMSecureRandom算法替换SHA1PRNG算法:
public ContinuationsManagerImpl() throws Exception {
random = SecureRandom.getInstance("SHA1PRNG");
try {
random = SecureRandom.getInstance("SHA1PRNG");
}
catch(java.security.NoSuchAlgorithmException nsae) {
// maybe we are on IBM's SDK
random = SecureRandom.getInstance("IBMSecureRandom");
}
random.setSeed(System.currentTimeMillis());
bytes = new byte[CONTINUATION_ID_LENGTH];
}
然后重新编译ContinuationsManagerImpl.java,并将其类文件替换Cocoon的jar包中原来的文件即可。
除了以上的问题,Cocoon框架自身可能会存在一些bug。所以如果有问题可以查看
http://cvs.apache.org/上的Cocoon的更新,以获得更佳稳定的Cocoon框架。以上是在WebSphere应用服务器5.0.2版本上部署Cocoon框架2.0和2.1版本的主要问题。
参考资料
- IBM WebSphere Application Server V5.1 System Management and Configuration(SG24-6195)
- WebSphere Studio Application Developer Version 5 Programming Guide(SG24-6957)
作者简介  | 
|  | 白钢,IBM公司中国软件开发中心高级软件工程师,主要从事WebSphere Application Server以及WebSphere MQ、MQ Integrator, MQ Workflow, WBI Server Foundation)等软件的技术支持与服务,并且是IBM全球高性能随需应变解决方案小组(HiPODS)的中国区组长,具有五年的J2EE应用设计和实施经验。您可以通过
baigang@cn.ibm.com与白钢联系。
|
 | 
|  | 张羽,现在从事WebSphere家族产品方面的技术支持工作,是WebSphere Application Server、WebSphere MQ、WBI Message Broker、WBI Server Foundation等企业整合软件方面的专家。通过了多项专业认证,包括IBM OOAD Professional、IBM DB2 Admin、Oracle Certified Professional、IBM WebSphere Studio Enterprise V5.0等,并且有丰富的J2EE应用设计、开发和移植经验。您可以通过
zhangyyu@cn.ibm.com与张羽联系。
|
对本文的评价
|