strange "String index out of range: 0" error

Cristian Boariu picture Cristian Boariu · Mar 4, 2010 · Viewed 21.7k times · Source

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.

Answer

BalusC picture BalusC · Mar 4, 2010

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.