Consider this JSF view snippet: ---------------------------------------------------------------------- <h:form> <h:commandButton value="submit" action="#{bean.submit('FOO')}" /> </h:form> ---------------------------------------------------------------------- And this JSF bean snippet: ---------------------------------------------------------------------- @ManagedBean @RequestScoped public class Bean { public enum Type { FOO, BAR } public void submit(Type type) { System.out.println(type); } } ---------------------------------------------------------------------- This results in a javax.el.MethodNotFoundException. It works in Glassfish 3. EL 2.2 spec 1.18.6 tells that a string must be coerced to enum of type T.
What stacktrace is there in MethodNotFoundException?
Here it is: javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException: /index.xhtml @15,58 action="#{bean.submit('FOO')}": Method not found: com.example.Bean@385c1187.submit(java.lang.String) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:92) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) at javax.faces.component.UICommand.broadcast(UICommand.java:315) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) Caused by: javax.el.MethodNotFoundException: /index.xhtml @15,58 action="#{bean.submit('FOO')}": Method not found: com.example.Bean@385c1187.submit(java.lang.String) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) ... 24 more
There is nothing in your stacktrace that comes from Tomcat EL implementation. There should be other "Caused by" somewhere further. Looking at method selection code in javax.el.BeanELResolver#invoke(..) - The "paramTypes" argument there is usually null. In that case the method is identified by the count of parameters, not by their types. If that were the case, type coercion will happen later and would not result in MethodNotFoundException. So where is it thrown from? - If the "paramTypes" argument is not-null then it will be used to select exact method. Is it your case? The requirements for BeanELResolver#invoke() API are set in EL 2.2 specification (see 2.2.9, page 38). I see no provision to respect EL coercion rules when paramTypes != null.
It's indeed been swallowed/wrapped by Facelets. Here's the stacktrace as it is coming from `invoke()`: javax.el.MethodNotFoundException: Method not found: com.example.Bean@66a01572.submit(java.lang.String) at org.apache.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:225) at org.apache.el.parser.AstValue.invoke(AstValue.java:251) at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) at javax.faces.component.UICommand.broadcast(UICommand.java:315) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722)
Indeed, the params being passed is null in Tomcat 7.0.26 while it contains the right values in Glassfish 3.x.
This has been fixed in trunk and 7.0.x and will be included in 7.0.27 onwards.