5

I have a URL like,

http://localhost:8080/Project-war/utility/Login.jsf?fallback=%2FProject-war%2Fpublic_resources%2FShowDetails.jsf%3Fid%3D9

This URL is formed, when a login page is requested. The return URL to which the request is to be redirected after successful login is appended as a query-string parameter to the URL.


If this URL is deliberately changed by a user like so,

http://localhost:8080/Project-war/utility/Login.jsf?fallback=%2FProject-war%2Fpublic_resources%2FShowDetails.jsf%3Fid%

A few trailing characters have been removed. It is a mal-formed URL. In this case, it causes the following exception to be thrown.

WARNING:   Error invoking requestInitialized method on ServletRequestListener org.jboss.weld.servlet.WeldListener
java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern
    at org.glassfish.grizzly.http.util.URLDecoder.decode(URLDecoder.java:488)
    at org.glassfish.grizzly.http.util.Parameters.processParameters(Parameters.java:654)
    at org.glassfish.grizzly.http.util.Parameters.processParameters(Parameters.java:692)
    at org.glassfish.grizzly.http.util.Parameters.handleQueryParameters(Parameters.java:335)
    at org.glassfish.grizzly.http.server.Request.parseRequestParameters(Request.java:1995)
    at org.glassfish.grizzly.http.server.Request.getParameter(Request.java:1052)
    at org.apache.catalina.connector.Request.getParameter(Request.java:1547)
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:448)
    at org.jboss.weld.servlet.ConversationContextActivator.getConversationId(ConversationContextActivator.java:115)
    at org.jboss.weld.servlet.ConversationContextActivator.activateConversationContext(ConversationContextActivator.java:82)
    at org.jboss.weld.servlet.WeldListener.requestInitialized(WeldListener.java:201)
    at org.apache.catalina.core.StandardContext.fireRequestInitializedEvent(StandardContext.java:5225)
    at org.apache.catalina.core.StandardHostValve.preInvoke(StandardHostValve.java:647)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:166)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)

SEVERE:   Error Rendering View[/utility/Login.xhtml]
java.lang.IllegalStateException: A request must be associated with the context in order to load the known conversations
    at org.jboss.weld.context.AbstractConversationContext.getCurrentConversation(AbstractConversationContext.java:390)
    at org.jboss.weld.jsf.ConversationAwareViewHandler.getActionURL(ConversationAwareViewHandler.java:102)
    at com.sun.faces.renderkit.html_basic.FormRenderer.getActionStr(FormRenderer.java:250)
    at com.sun.faces.renderkit.html_basic.FormRenderer.encodeBegin(FormRenderer.java:143)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:864)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at filter.LoginNocacheFilter.doFilter(LoginNocacheFilter.java:39)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)

WARNING:   Error invoking requestDestroyed method on ServletRequestListener org.jboss.weld.servlet.WeldListener
java.lang.NullPointerException
    at org.jboss.weld.context.AbstractBoundContext.deactivate(AbstractBoundContext.java:71)
    at org.jboss.weld.context.http.HttpRequestContextImpl.deactivate(HttpRequestContextImpl.java:70)
    at org.jboss.weld.servlet.WeldListener.requestDestroyed(WeldListener.java:154)
    at org.apache.catalina.core.StandardContext.fireRequestDestroyedEvent(StandardContext.java:5261)
    at org.apache.catalina.core.StandardHostValve.postInvoke(StandardHostValve.java:255)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:359)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)

This exception occurs internally and is not caused by the code I wrote. This exception should not occur.

How to tackle/handle this exception?

Tiny
  • 27,221
  • 105
  • 339
  • 599
  • Are you saying that when the URL is modified by the user, the exception occurs before your Login.jsf ever gets called? – Jim Rhodes Jul 27 '14 at 13:15
  • Yes a user might feel like playing with a URL. If the URL is modified on the `Login.jsf` page just for having a fun, this exception is thrown. The process of login is too far from there. The submit button for login is not even clicked by the user. The exception occurs, when a user just makes such unexpected changes to URL in the browser's address bar itself and strikes the enter key. – Tiny Jul 27 '14 at 13:23
  • 1
    This can't be solved from JSF side on. This is a bug in GlassFish 4.0 itself which has its consequences into among others CDI/JSF. It happens already low level before the `FacesServlet` got chance to run. GlassFish should actually be skipping the malformed parameter instead of throwing an exception, killing the entire webapp. Other servers like TomEE/WildFly also just skip this kind of params and merely log a warning. Replacing the `nucleus-grizzly-all.jar` in GlassFish `/modules` folder with the one attached in [this issue](https://java.net/jira/browse/GLASSFISH-20840) should solve this. – BalusC Aug 10 '14 at 07:09
  • @BalusC : I replaced that JAR file (cleaning osgi-cache and other dump activities) but the exception is still going on. Additionally it is not going to work at other places because replacing this JAR causes this exception `java.io.IOException: java.util.concurrent.TimeoutException`, [a bug](https://java.net/jira/browse/GLASSFISH-20681) I once faced while reading large BLOB objects on GlassFish 4 that requires `nucleus-grizzly-all.jar` to be replaced by the one mentioned in that link (I had been using that new JAR since then). So is the only solution to keep waiting for the next release? :) – Tiny Aug 10 '14 at 08:56
  • 1
    There's nothing you can do about a user playing with the URL. He will always be able to devise something illegal or poorly-behaving. – user207421 Aug 10 '14 at 09:53
  • Oh, you're already using the in issue 20681 attached JAR file? Okay, that's new information to me. I'll perhaps try to reproduce this myself later. By the way, I won't expect new GlassFish releases soon. Oracle [stopped](http://blog.arungupta.me/2013/11/glassfish-commercial-is-dead-wildfly-and-jboss-eap-to-rescue) with commercial support on GlassFish (hereby pushing the focus towards WebLogic). These days, you'd better grab WildFly (Oracle/JBoss minded) or TomEE (Apache minded) as alternative to open source edition of GlassFish. – BalusC Aug 10 '14 at 18:44
  • @BalusC : I thought of using WildFly nowadays but I will have to start completely a new chapter slowly :) (I never used jboss either). – Tiny Aug 10 '14 at 18:50
  • Reproduced. There's no feasible workaround without altering the GlassFish source code. I tried it with a servlet request wrapper which suppresses the exception and continues, but Weld's `ServletRequestListener` is registered very early in server's startup and there's no way to register the custom request wrapper before Weld initializes and registers its own. – BalusC Aug 14 '14 at 17:12
  • @BalusC : Let it go, no worry. – Tiny Aug 14 '14 at 18:58

2 Answers2

4

This is a bug in GlassFish4.

There's no way to solve this problem from the webapp side on. Not with a Filter, not with a ServletRequestListener, not with a ServletContainerInitializer, even not with a GlassFish-specific GlassFishValve. The one responsible for determining the request parameter and thus triggering this GlassFish bug, Weld, is initialized very early in GlassFish's startup in GlassFish's own WebConfigListener. Due to this tight-coupling of GlassFish and Weld, there's no way to run some code before Weld's ServletRequestListener, the WeldListener, gets triggered. If it were possible, then you could just call request.getParameterMap() inside a try-catch before delegating.

Your best bet is reporting this as another issue to GlassFish. However, as Oracle has stopped with commercial support for GlassFish, you shouldn't expect new open source GlassFish releases soon. These days, you'd better grab WildFly (Oracle/JBoss minded and already Java EE 7 ready) or TomEE (Apache minded, but not Java EE 7 ready yet) as alternative to open source edition of GlassFish. Those servers are smart enough to just skip this kind of corrupted request parameters and merely log a warning instead of throwing an IllegalArgumentException which kills the entire web application.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • The exception mentioned in the question does not occur in GlassFish 4.1. Instead it just prompts a message on the server terminal with the log level `INFO`, if decoding fails in any case like, `INFO: GRIZZLY0156: Character decoding failed. Cause: [URLDecoder: Incomplete trailing escape (%) pattern]. Parameter [fallback] with value [/Project-war/public_resources/ShowDetails.jsf?idjsf%3Fid%] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use FINEST level logging to see the original, non-corrupted values.` – Tiny Oct 22 '14 at 16:12
  • 1
    Is it fixed in Glassfish 4.1? – jakentus Dec 05 '14 at 13:34
-2

Don't put the return URL in the query string. Embed it in the page, or put it in a session variable (cookie).

kdkeck
  • 2,097
  • 1
  • 14
  • 10
  • I did read the question, but perhaps I did misunderstand what you are looking for. Am I to understand that you want to let the user mess with the URL all they want, you just want to make sure you catch the exception if the resulting URL is malformed? – kdkeck Aug 15 '14 at 17:39