技术开发 频道

Cocoon的移植问题

  【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文件中掺杂在load-class中的注释。

  问题三: Cocoon框架中的sitemap规范中的某些功能无法生效,例如:

1   <map:match pattern="documents/index">
2         <map:redirect-to uri="index.html" />

  问题分析:由于WebSphere应用服务器的5.0.2版本没有完全遵从Servlet 2.3规范,所以导致上述错误。

  解决方案:对于Cocoon 2.0.4和2.1,我们应当做如下的修改:

1 <map:match pattern="document/index">
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.(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.(ContinuationsManagerImpl.java:119)

  ......

  问题分析:由于WebSphere应用服务器5.0.2版本所使用的IBM SDK不包含对SHA1PRNG算法的支持,所以会有上述错误发生。

  解决方案:需要对 /src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java进行修改,用IBMSecureRandom算法替换SHA1PRNG算法:

1 public ContinuationsManagerImpl() throws Exception {
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版本的主要问题。

0
相关文章