my dog learned polymorphism*
The moose likes JSF and the fly likes IndexOutOfBoundsException in JSF primeface menu item Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "IndexOutOfBoundsException in JSF primeface menu item" Watch "IndexOutOfBoundsException in JSF primeface menu item" New topic
Author

IndexOutOfBoundsException in JSF primeface menu item

K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Hello rancher

I have a JSF app using Primefaces. I have a menu at the top of the page.


When the app timed out, when the menu item clicked, nothing seems to happen. Then if I click logout or another menu item the IndexOutOfBoundsException occur.

The pageForwardBean.goHome looks like


Utility.cleanupSessionAttributes();



The exception stack look like this:


exception

javax.servlet.ServletException: Index: 0, Size: 0
javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
com.df.lcs.common.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:23)
com.df.lcs.login.UserRoleAccessFilter.doFilter(UserRoleAccessFilter.java:40)
com.df.lcs.login.RestrictPageFilter.doFilter(RestrictPageFilter.java:33)

root cause

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
java.util.ArrayList.RangeCheck(ArrayList.java:547)
java.util.ArrayList.get(ArrayList.java:322)
javax.faces.component.AttachedObjectListHolder.restoreState(AttachedObjectListHolder.java:161)
javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1428)
com.sun.faces.application.view.StateManagementStrategyImpl$1.visit(StateManagementStrategyImpl.java:242)
com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:147)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1476)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:234)
com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:177)
com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:119)
com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:438)
com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:144)
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:182)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
com.df.lcs.common.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:23)
com.df.lcs.login.UserRoleAccessFilter.doFilter(UserRoleAccessFilter.java:40)
com.df.lcs.login.RestrictPageFilter.doFilter(RestrictPageFilter.java:33)


I don't know if such issue is cause by the fact I used Primeface's upload servlet org.primefaces.webapp.filter.FileUploadFilter for file upload.

I'm using JBoss 6.1 and JSF 2.1 and Primeface 3.5

Any thoughts? Thanks


K. Tsang JavaRanch SCJP5 SCJD/OCM-JD OCPJP7 OCPWCD5 OCPBCD5
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16233
    
  21

This is another one of those cases where I'm not actually sure what's going on, but I'll make a few observations in the hopes that it will help.

First of all, remember JSF Rule #1: The more JSF-specific you solution is, the more likely it's a bad solution.

I don't think I have a single JSF webapp that uses actionListeners. There is a use for them, but 99.999998% of the time, a simple POJO action method is all that you need. Especially since in your example, I'm not sure your listener method has the right signature.

I'm guessing that you want the menu to alter itself. Rather that an complex running around in the JSF internals, I'd use a binding if I needed access to the UI component or its related menu items and if the map is supposed to be retrieving JSF managed beans, I'd simply inject them as managed properties. JSF is all about Inversion of Control, where you don't go looking for things, things are delivered to you automatically.

Incidentally, you don't need to code a method at all in JSF to navigate to a fixed target. You can just do this:



Or if you want to use faces-config, this is something I do a lot:


In which case, just code the following:



Customer surveys are for companies who didn't pay proper attention to begin with.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Thanks Tim

Given I use the filename directly in the p:menuItem like you suggested, then my pageForwardBean is practically pointless. Yet is the cleanupSessionAttribute() method needed? Because I do this to prevent too much object in stack or memory / session avoiding errors like StackOverflowError.

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16233
    
  21

Yep, the pageForwardBean is redundant here. Another case where JSF tries to minimize the amount of coding you need to do.

As far as memory goes...

Stack space is not an issue. The stack grows and shrinks with the methods that are invoked. So simply returning from the methods frees up the stack memory. If you have a stack overflow, it's usually due to excessive (if not infinite) recursion.

Heap space is a different matter. The JSF View scope was created to help with that. So was J2EE Request scope, but as I've often mentioned, Request scope doesn't work well in JSF.

All View scope really is is Session scope with an automatic free-up mechanism. JSF2 also added a custom scope mechanism, when you need something in between View scope and full Session scope. It's very badly explained, but the gist of it is that if you have a workflow where you are juggling a set of beans to get the job done, you can put them in a private dictionary (Map) and add logic to clear out the map when the workflow is done. As raw as it is, I expect (hope) that eventually a cleaner approach will eventually be developed.

In the mean time, I usually have a method in my catch-all JSFUtils bean that can accept a backing bean as an argument and will then remove it from the HttpSession. Since the bean doesn't actually get deleted at that time, I have unhooked it from the session - meaning that after I've finished with my request, it's eligible for garbage collection - but I can continue to execute within the bean. Normally I have a "cancel" action method that handles this, and it's invoked internally as well for non-cancel operations that have finished using the bean and want to clean up. Since the cancel method may be bypassed (for example, if the user directly jumps to a new URL, there's also an init() method that contains the code to reset the bean's state if it's about to be re-used but wasn't deleted and then re-created.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Thanks for the advice Tim. After considering, I kept the pageForward bean.

After some time fiddling with code, I wasn't able to figure out why IndexOutOfBoundsException can be thrown. I even tried comment/ignore the Primeface FileUploadFilter but that wasn't it.

Then I print the stack trace and found it's some render problem not able to find some component with id "blablabla". Then I added in the id for the menu items and such.... still got same exception.

Then to solve this, I kind of catch the exception and rethrow it in one of my filters. Since it's a ServletException I did



This at least prevent the end user to see the exception in the browser. Yet in the app server's log, there still that render problem mentioned above.

Not sure if this a JSF specific approach but it will have to work for now.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16233
    
  21

The (POJO) action method version of returning to the home page looks like this:


If you have a ViewExpiredException, there are ways of handling that, although it sounds more like you are dealing with a stale View that's out of sync. You might could fix it using some of the documented recovery techniques, but if you're writing strange listeners or otherwise putting kinks in the normal JSF lifecycle processing, it might get complicated.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Actually the IOOBE doesn't happen just at the menu items but any other page link and ajax call (eg update select one menu)

In fact in my app there is a ExceptionHandler to handle so-called FacesException like ViewExpiredException, which forward to some error page with stack trace. Yet in the beginning of the project, that error page once in a while pops up. But towards the end of the project, if it did try to get to the error page StackOverflowError occurs. This is weird to me.

Anyhow the StackOverflowError seldomly happens unless 1) session timed out AND 2) the page's managed bean is session scoped and 3) user physically refresh the page like clicking back button.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: IndexOutOfBoundsException in JSF primeface menu item