解惑

解己之惑,解人之惑

标签:Pluto

Pluto的session问题

按照JSR168规范的说明,在Portlet中,我们可以通过PortletSession访问存储在HttpSession中的属性,我看了Pluto的实现,也确实是这样做的:
    // PortletSession Impl: Attributes —————————————–
   
    public Object getAttribute(String name) {
        return getAttribute(name, DEFAULT_SCOPE);
    }
   
    /**
     * Returns the attribute of the specified name under the given scope.
     *
     * @param name  the attribute name.
     * @param scope  the scope under which the attribute object is stored.
     * @return the attribute object.
     */
    public Object getAttribute(String name, int scope) {
        ArgumentUtility.validateNotNull("attributeName", name);
        String key = (scope == PortletSession.APPLICATION_SCOPE)
                ? name : createPortletScopedId(name);
        return httpSession.getAttribute(key);
    }

但是当我把pluto集成到我们的应用里面的时候,问题就来了,用户登录后,访问其它的页面和访问portlet的页面的时候的session id是不同的,历经磨难,找到一些前人的文章:

 
From testing with Jetspeed/Pluto on Tomcat 5.0 and the default configuration of 5.5, servlets accessed directly do not share the portlet session. In Tomcat 5.5 configured with emptySessionPath="true", behaviour is correct as described in the portlet specification.

So, to summarize what I’ve learned, if you need to pass session objects from a portlet to a servlet using Pluto as your servlet container, the following three conditions must all be true:

  1. You must run Tomcat 5.5.x, or later.
  2. You must set crossContext="true" in your web app’s element.
  3. You must set emptySessionPath="true" in the element in Tomcat’s server.xml file.

If you omit any one of these three steps, it won’t work.

所以问题的核心就是emptySessionPath,在我们的环境中使用的是tomcat5.0,crossContext是设置为true的。

2007年3月21日下午更新:
集成中的问题是我犯了一个错误,我在获取HttpSession中的属性的时候忘了应该使用APPLICATION_SCOPE,而不同的session id是因为我的另外的代码导致的(我写了一个Bridge类去获得Struts的Action的执行结果并输出,在Bridge中的请求相当于另外一个客户端)。
从Portlet中,使用RenderRequest..getPortletSession().getAttribute("xxxx", PortletSession.APPLICATION_SCOPE)就可以拿到其它的普通servlet和jsp中设置的值了。

Pluto admin在IE下不工作

这里的不工作是指添加删除按钮不工作,点击完全没有反应,解决办法是WEB-INF\fragments\admin\page\view.jsp,给button标签加上type="submit",这样按钮就有反应了(可能还会有其它的BUG,我是直接升级到这个文件的最新版本的),但是这不能解决全部的问题,因为添加按钮不能完全正常工作,你只能给第一个页面添加portlet,如果你选择了其它的页面,然后想用下面的添加按钮给那个页面添加portlet,结果是你的点击不会产生任何效果,因为后台prtolet认为是remove操作,但是没有选择要删除的portlet,解决办法是修改PageAdminPortlet:
        String availablePortlets = request.getParameter("availablePortlets");
        if(availablePortlets!=null) {
            doAddPortlet(request);
        }
        else {
            doRemovePortlet(request);
        }
这样做其实也是有问题的,就是如果你在下面选择了想添加的portlet,但是实际点击的是remove按钮,其结果和你预期的不同。

其实所有的这些问题都是源于Pluto不成熟,它只是给出了一个最最简单的参考,并没有经过充分的测试,而且它的开发人员可能是使用FF作为测试的主要浏览器的。

JSR168

JSR168规范是定义portlet容器及portlet之间的关系的,但是由于定稿比较早(2003年10月),所以没有涉及到portlet的独自渲染和刷新,而这个是现在的web2.0或者新一代web界面所不可或缺的,当然,新的JSR286规范可能会解决这个问题,但是我们不能等待这个规范的出台。就目前的情况看,融合jsr168和AJAX并不会很困难,问题的关键是没有一个轻量的组件或者成熟的解决方案,有的只是大的软件厂商在他们的portal产品中提供这种特性的支持。这段时间一直在用pluto,刚刚整合到我们的系统中,看了下pluto最终渲染出来的页面片断:
  <!– Assemble the rendering result –><br />
 
<div id="/testsuite.TestPortlet!764587357|0" class="portlet"><br />
  
<div class="header"><br />
      <!– Portlet Mode Controls –><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_view"><span class="view"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_edit"><span class="edit"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_help"><span class="help"></span></a><br />
      <!– Window State Controls –><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_minimized"><span class="min"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_maximized"><span class="max"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_normal"><span class="norm"></span></a><br />
      <!– Portlet Title –><br />
    
<h2 class="title">Test Portlet #1</h2>
<br />
    </div>
<br />
  
<div class="body"><br />
从这个输出来看,我们需要做的可能很简单,替换portlet-skin.jsp,重新定义那些按钮的输出为一个javascript,这样应该就可以部分刷新了。目前我们产品的其它一个功能已经可以做到这个了。现在的问题就是转换了。

为什么要使用Pluto?

这两天一直在看Pluto的东西,给我的感觉一直都不是很好,随着了解的深入,这种感觉越来越明显,其实也不是别的,就是它的要求太高了,它所声明的一些东西它又没有真正做到(例如可以运行在JDK1.4下,可以在Tomcat5.0下运行),但是同时它又不是一个完善的Portal框架,因为它所提供的功能实在是太少了,它只是提供了一个JSR168规范的参考实现。我到现在都不明白美国那边的架构师为何要选择它,在我们研究后说它不能在JDK1.4下运行时,他们竟然一再质疑我们的结论。在我今天成功的发布到Tomcat5.0.28后,我想将它集成到我们的产品中,结果又出问题,原因也很简单,就是要把应用配置为crossContext的,但是我不知道如何设置,因为我们的产品使用的是Jboss+tomcat,那个pluto.xml文件是自动生成的,我手工修改也没有用。后来再研究了下,可能要修改jboss-web.xml文件,到了下班的时间就回来了,明天再试试了。不过明天我会和美国的架构师讨论下,我考虑使用Light Portal,因为它提供的功能更丰富,可以大大减少我们的工作量(包括AJAX的拖放式配置效果)。

将Pluto1.1发布到Tomcat5.0

上次也已经提到了很难将Pluto1.1发布到Tomcat5.0,经过另外几个小时的艰苦努力,总算是成功了。
第一是因为它使用了一个JDK1.5的API,解决方法是修改org.apache.pluto.core.ContainerInvocation,将CONTAINERS.remove();注释掉。(可能有潜在的问题,猜测可能是会有内存泄漏)
第二是它提供的参考实现的war包的配置使用了testsuite那个应用,必须修改pluto-portal-driver-config.xml,删除其中对testsuite应用的portlet的引用:
<?xml version="1.0" encoding="UTF-8"?>

<pluto-portal-driver
    xmlns="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd
                        http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
    version="1.1">

    <portal-name>pluto-portal-driver</portal-name>
    <portal-version>1.1.0</portal-version>
    <container-name>Pluto Portal Driver</container-name>

    <supports>
        <portlet-mode>view</portlet-mode>
        <portlet-mode>edit</portlet-mode>
        <portlet-mode>help</portlet-mode>
        <portlet-mode>config</portlet-mode>

        <window-state>normal</window-state>
        <window-state>maximized</window-state>
        <window-state>minimized</window-state>
    </supports>

    <!– Render configuration which defines the portal pages. –>
    <render-config default="About Pluto">
        <page name="About Pluto"
            uri="/WEB-INF/themes/pluto-default-theme.jsp">
            <portlet context="/pluto" name="AboutPortlet" />
        </page>
        <page name="Pluto Admin"
            uri="/WEB-INF/themes/pluto-default-theme.jsp">
            <portlet context="/pluto" name="PlutoPageAdmin" />
            <portlet context="/pluto" name="AboutPortlet" />
        </page>
    </render-config>

</pluto-portal-driver>

阅读全文

痛苦的Pluto使用经历

项目中要使用到Pluto,今天研究了一下,但是经历着实痛苦。
我们的tomcat使用的是古老的jboss带的版本,我就用我自己安装的tomcat5.0.28做了下试验,结果不成功,后来下载了一个bundle版本,其实就是已经包含了tomcat的版本,但是它带的版本是5.5.20,我就对照了下,把我能看出来的不同都对应的在tomcat5.0.28下做了修改,应用是可以跑起来了,但是登录进首页的时候出了一个NullPointerException,原因不明也没有那么多时间去研究,后来就下载了老版本的1.0.1试验,结果应用都不能起来。没有办法,只能从原代码编译试试,又去下载maven,结果使用JDK1.4无法编译,它的代码中使用了一个JDK1.5才有的方法,手工修改源代码,编译通过了,但是在安装的时候又出了问题,报告pluto的一个plugin不存在。然后又下载pluto的1.0.1版本的原代码,又下载maven1.0.2版本编译,依然不成功,原因是不能解析project.xml文件,彻底无语了。

更新:
回家后又弄了一下,终于在tomcat5.0.28下成功手工发布了pluto1.1,问题是我依然要使用JDK1.5才能看到结果运行正常,使用JDK1.4时会出现编译pluto1.1时遇到的那个问题的运行期版本。步骤为将bundle版本下的文件拷贝到tomcat5.0.28的对应目录:

  • conf\Catalina\localhost\pluto.xml
  • \shared\lib
  • \PlutoDomain\pluto-portal-1.1.0.war
  • 编辑tomcat-users.xml文件,增加pluto用户

要解决JDK版本问题,可能的办法就是修改源代码(pluto-1.1.0-src\pluto-container\src\main\java\org\apache\pluto\core\ContainerInvocation.java,把64行注释掉就行)后在JDK1.4下编译,然后把那个有问题的类替换掉,当然可能会有其他的问题。

© 2020 解惑

本主题由Anders Noren提供向上 ↑