5

I have a huge application and at some point, when a redirect is involved i received this strange error:

Caused by java.lang.StringIndexOutOfBoundsException with message: "String index out of range: 0"    
java.lang.String.charAt(String.java:687)
com.sun.faces.application.ViewHandlerImpl.getActionURL(ViewHandlerImpl.java:652)
org.jboss.seam.jsf.SeamViewHandler.getActionURL(SeamViewHandler.java:74)
com.sun.facelets.FaceletViewHandler.getActionURL(FaceletViewHandler.java:803)
org.ajax4jsf.application.ViewHandlerWrapper.getActionURL(ViewHandlerWrapper.java:86)
org.jboss.seam.ui.util.ViewUrlBuilder.<init>(ViewUrlBuilder.java:25)
org.jboss.seam.ui.component.UISeamCommandBase.getUrl(UISeamCommandBase.java:48)
org.jboss.seam.ui.renderkit.LinkRendererBase.doEncodeBegin(LinkRendererBase.java:26)
org.jboss.seam.ui.util.cdk.RendererBase.encodeBegin(RendererBase.java:79)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:813)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:934)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:942)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:942)
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:109)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
org.jboss.seam.web.RewriteFilter.doFilter(RewriteFilter.java:63)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
java.lang.Thread.run(Thread.java:619)

I've spent two hours debugging and so on, but did not find any clue... It's just weird because the error log does not tell something clear...(which string, which property is involved etc).

Does anyone can guess something more from the stacktrace?

Thanks.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

3 Answers3

14

Let's check what ViewHandlerImpl#getActionURL() does (Mojarra is just open source). Here's is a summarized/stripped extract of the method as it is in Mojarra 2.0.2:

public String getActionURL(FacesContext context, String viewId) {
    if (context == null) throw new NullPointerException();
    if (viewId == null) throw new NullPointerException();
    if (viewId.charAt(0) != '/') throw new IllegalArgumentException();
    // ...

In other words, the passed-in viewId is an empty string instead of null or / or the normal path. The Mojarra viewhandler didn't expect it at all, hence this runtime exception. It can be a bug in the view handler of Mojarra that it should handle empty strings as well, but it can also be a bug in the view handler of either Ajax4jsf, Facelets or Seam that it should never pass an empty string through up. It can also be a bug in your own code that you're actually passing an empty string as view ID.

If the problem isn't in your code, then I would start with upgrading what can be upgraded to see if it resolves the problem. Maybe it was already reported before as a bug and fixed in a newer release. If that doesn't help, I would check the classpath for duplicate JAR files of different versions which might have collided with each other.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC. I've clearly put a non empty string in the viewId and with debug i 've double checked:redirect.setViewId(portalConfiguration.getInboxPage()); which is not null and not empty.... – Cristian Boariu Mar 04 '10 at 14:28
  • Of course....there i had a property on that viewId to which i redirect, which was null !!! Oh.................................Thanks Balus for you answer. – Cristian Boariu Mar 04 '10 at 14:55
  • ...is it too much to hope that someone will update the Mojarra source to handle this case? – Alex Feinman Jun 18 '10 at 17:33
  • @Alex: they can at highest add an extra check and throw a more clarifying exception instead. To get them to add that you'll need to post an [issue](https://javaserverfaces.dev.java.net/issues/). I've done it for you: [issue 1712](https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1712). – BalusC Jun 18 '10 at 17:45
4

My first guess would be that you have an empty string "", of which you are trying to get the first character (at index 0)

Jorn
  • 20,612
  • 18
  • 79
  • 126
0

In my case i ve solved the issure reviewing all my page´s ids. I was rendering a facelet in two cases and in one of those there was a reference to an id that not existed.

In my jsf facelet: The reference to #{finishBtn} did not exists because it was not passed from the page which called this.

<ui:composition>
    ......
    ....
     <a4j:commandButton title="#{i18n.editar_er_tip}"
                        image="/images/edit.png" style="width:16px;height:16px" reRender="entregablesTable,#{finishBtn},entregableBotton"
                        action="#{actionBean[editMethod]}"
                        onclick="Richfaces.showModalPanel('waitPanel')"
                        oncomplete="Richfaces.hideModalPanel('waitPanel');Richfaces.showModalPanel('entregableBotton')">
    </a4j:commandButton>
    ....
    ..
</ui:composition>

I have solved with a previous evaluation

<c:if test="${empty finishBtn}">
        <c:set var="finishBtn" value="editButton" />
</c:if>
AntuanSoft
  • 343
  • 2
  • 9