[ 
https://issues.apache.org/jira/browse/PB-84?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ate Douma updated PB-84:
------------------------

    Attachment: portals-bridges-common-1.0.4.jar

The above is an incorrect assessment of how the code works.
And, although this "issue" has been brought up before, in my view the CCE 
thrown by OpenPortal (as well as JBoss Portal AFAIK) is a bug in the portlet 
container, *not* this method.

If you look at the rest of following code within this method, you'll notice the 
*random* generated Double object put in the session is put in there only for a 
for a very short time
and *replaced* within the same method almost immediately with a String object.

The whole point of this method is determining what the container provided 
PORTLET_WINDOW_ID is using a JSR-168 compliant "trick", in that PORTLET_SCOPE 
session attributes
are stored within the session using a predefined format which includes the 
PORTLET_WINDOW_ID (see: JSR-168 spec PLT.15.3).

For that purpose, a reasonably unique (double) value is generated using 
Math.random() and stored as a Double value within the session under 
PORTLET_SCOPE for an internal defined attribute name, 
"org.apache.portals.bridges.util.portlet_window_id".
Thereafter, all the APPLICATION_SCOPE  attributes are evaluated, looking again 
for this internal attribute name 
("org.apache.portals.bridges.util.portlet_window_id") and (as an extra save 
guard)
its value is checked against the previously generated Double value to be sure 
the correct attribute value (name) is found.

Then, the temporary Double value is *replaced* with the real (String type) 
PORTLET_WINDOW_ID.

If the portlet container is implemented and behaving compliant to JSR-168, the 
above routine should work as expected and the temporary Double value should 
always be replaced again with a String value *within* the same method.
Also note: this part of the method is executed within a sychronized block so 
interference of other requests should not be possible either.

The fact this method fails (sometimes?) on OpenPortal and JBoss Portal in my 
view is very suspicious.
Somehow, the "org.apache.portals.bridges.util.portlet_window_id" attribute 
stored under PORTLET_SCOPE seems not be found correctly under SESSION_SCOPE, in 
which case this method will return null (this first time).
Subsequently, the following call to this method will indeed cause a CCE, sure.

Although I'd like to "fix" this problem, or even use a proper work around if 
possible, simply using the (obviously a Double) value as an Object won't help 
here.
Note: this method is supposed to return a String value and specifically a 
PORTLET_WINDOW_ID.

Until it is more clear what goes wrong here and why these portlet containers 
are not behaving as expected, I have no real solution available.

Tim, as you're encountering this problem with OpenPortal, it would be great if 
you could try to determine in more detail what goes on here.
I've created a modified version of the getPortletWindowId method which will 
produce some stack trace logging to the console which might tell us more  
(note: requires Java 1.5):

    public static String getPortletWindowId(PortletSession session)
    {
        System.out.println("getPortletWindowId for session: 
"+session.getId()+"(thread: "+Thread.currentThread().getId()+")");
        
        String portletWindowId = 
(String)session.getAttribute(PORTLET_WINDOW_ID);
        if ( portletWindowId == null )
        {
            synchronized (session)
            {
                System.out.println("  no portletWindowId yet - going to derive 
it. Current thread ("+Thread.currentThread().getId()+") call stack:");
                for (StackTraceElement st : 
Thread.currentThread().getStackTrace()) System.out.println(st);                
                Double value = new Double(Math.random());
                session.setAttribute(PORTLET_WINDOW_ID, value);
                Enumeration names = 
session.getAttributeNames(PortletSession.APPLICATION_SCOPE);
                System.out.println(" looking for attribute 
"+PORTLET_WINDOW_ID+" in current APPLICATION_SCOPE attributes:");
                while (names.hasMoreElements())
                {
                    String name = (String)names.nextElement();
                    System.out.println(" found attribute: "+name);
                    if 
(PortletSessionUtil.decodeAttributeName(name).equals(PORTLET_WINDOW_ID) && 
value.equals(session.getAttribute(name,PortletSession.APPLICATION_SCOPE)) )
                    {
                        portletWindowId = 
name.substring("javax.portlet.p.".length(),name.indexOf('?'));
                        System.out.println("  --> found - PORTLET_WINDOW_ID = 
"+portletWindowId);
                        session.setAttribute(PORTLET_WINDOW_ID, 
portletWindowId);
                        break;
                    }
                }
                if (portletWindowId == null) System.out.println("  --> error: 
failed to derive the portletWindowId");                
            }
        }
        return portletWindowId;
    }

For your convenience I've attached a modified version of the 
portlet-bridges-common-1.0.4.jar with the above changed method compiled in it 
(again: using it requires Java 5).

I've run it myself (on Pluto/Jetspeed-2) which produces the following output 
(stack trace dump truncated for brevity):

  getPortletWindowId for session: FC9065541BED56975E35C1AD97BAB419(thread: 55)
    no portletWindowId yet - going to derive it. Current thread (55) call stack:
  java.lang.Thread.dumpThreads(Native Method)
  java.lang.Thread.getStackTrace(Thread.java:1383)
  
org.apache.portals.bridges.util.PortletWindowUtils.getPortletWindowId(PortletWindowUtils.java:53)
  
org.apache.portals.bridges.util.ServletPortletSessionProxy.createProxy(ServletPortletSessionProxy.java:59)
  
org.apache.portals.bridges.struts.StrutsPortlet.processRequest(StrutsPortlet.java:420)
  org.apache.portals.bridges.struts.StrutsPortlet.doView(StrutsPortlet.java:301)
  javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:247)
  javax.portlet.GenericPortlet.render(GenericPortlet.java:175)
  
org.apache.jetspeed.factory.JetspeedPortletInstance.render(JetspeedPortletInstance.java:103)
  
org.apache.jetspeed.container.JetspeedContainerServlet.doGet(JetspeedContainerServlet.java:277)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
  <snip/>
    looking for attribute org.apache.portals.bridges.util.portlet_window_id in 
current APPLICATION_SCOPE attributes:
    found attribute: 
javax.portlet.p.jp-2?org.apache.portals.bridges.util.portlet_window_id
    --> found - PORTLET_WINDOW_ID = jp-2

If you could try the same and provide me with the debug output you get, maybe 
we can get somewhat further with this problem.

Ate



> CCE in PortletWindowUtils.getPortletWindowId
> --------------------------------------------
>
>                 Key: PB-84
>                 URL: https://issues.apache.org/jira/browse/PB-84
>             Project: Portals Bridges
>          Issue Type: Bug
>          Components: common
>    Affects Versions: 1.0
>         Environment: Mac OS, Wicket Portlets, OpenPortal Portlet Container
>            Reporter: Tim Boudreau
>         Attachments: portals-bridges-common-1.0.4.jar
>
>
> I'm trying to get wicket portlet support working over OpenPortal.  I've 
> hacked together implementations of ServletContextProvider and 
> PortletResourceURLFactory - just required exposing WicketFilter from the 
> Application to get the necessary data.  I can deploy a portlet, but...
> I'm getting this exception. 
> java.lang.ClassCastException: java.lang.Double
>         at 
> org.apache.portals.bridges.util.PortletWindowUtils.getPortletWindowId(PortletWindowUtils.java:45)
> Looking at the code, this seems like a clear bug:  The method casts to String 
> here:
> (String)session.getAttribute(PORTLET_WINDOW_ID);
> and if null fills in the value with an instance of Double.  If it's going to 
> put a Double there, it should probably not expect a String - this exception 
> will occur any time this method is called twice for a PortletSession, it will 
> throw the CCE the second time it is called.
> Since the value is not used, probably simply changing it to 
>         Object portletWindowId = session.getAttribute(PORTLET_WINDOW_ID);
> would fix it.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to