1

Currently I'm using a datatable to display some items out of a database. Works fine.

<h:dataTable border="1" value="#{overviewBean.loadContent }" var="item" first="0" >
    <h:column id="column1">
        <f:facet name="header">
            <h:outputText value="#{messages.overviewSubscriptionID }"></h:outputText>
        </f:facet>
        <h:outputText value="#{item.subscriptionID }"></h:outputText>
    </h:column>
    <h:column id="column2">
        <f:facet name="header">
            <h:outputText value="#{messages.overviewCourseID}"></h:outputText>
        </f:facet>
        <h:outputText value="#{item.courseID }"></h:outputText>
    </h:column>
    ...
    <h:column id="column13">
        <f:facet name="header">
            <h:outputText value="#{messages.overviewDeleteItem }"></h:outputText>
        </f:facet>
        <h:commandButton action="#{overviewBean.delete}" value="X">
            <f:param name="delete" value="#{item.courseID}"></f:param>
        </h:commandButton>
    </h:column>
</h:dataTable>

Whenever now the param-tag is there, the page doesn't load. This is the exception that is thrown:

/overview.jsp(15,1) '#{overviewBean.loadContent }' java.lang.IllegalArgumentException
Caused by:
java.lang.IllegalArgumentException - java.lang.IllegalArgumentException


Edit: Because requested, I added the entire stacktrace (as seen on the generated page):
org.apache.jasper.el.JspELException: /overview.jsp(15,1) '#{overviewBean.loadContent }' java.lang.IllegalArgumentException
        at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:107)
        at javax.faces.component.UIData.getValue(UIData.java:1142)
        at javax.faces.component.UIData.createDataModel(UIData.java:1082)
        at javax.faces.component.UIData.getDataModel(UIData.java:1056)
        at javax.faces.component.UIData.getRowCount(UIData.java:449)
        at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeInnerHtml(HtmlTableRendererBase.java:234)
        at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeChildren(HtmlTableRendererBase.java:143)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:627)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:250)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257)
        at org.apache.myfaces.application.jsp.JspViewHandlerImpl.actuallyRenderView(JspViewHandlerImpl.java:427)
        at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:383)
        at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
        at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:140)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:187)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)
    Caused by: javax.faces.el.EvaluationException: java.lang.IllegalArgumentException
        at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:80)
        at org.apache.myfaces.el.convert.VariableResolverToELResolver.getValue(VariableResolverToELResolver.java:95)
        at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
        at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
        at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
        at org.apache.el.parser.AstValue.getValue(AstValue.java:112)
        at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
        at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
        ... 27 more
    Caused by: javax.el.ELException: java.lang.IllegalArgumentException
        at javax.el.BeanELResolver.setValue(BeanELResolver.java:116)
        at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:69)
        at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:182)
        at org.apache.myfaces.config.ManagedBeanBuilder.initializeProperties(ManagedBeanBuilder.java:268)
        at org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:92)
        at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.createManagedBean(ManagedBeanResolver.java:198)
        at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.getValue(ManagedBeanResolver.java:164)
        at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
        at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
        at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:65)
        ... 34 more
    Caused by: java.lang.IllegalArgumentException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at javax.el.BeanELResolver.setValue(BeanELResolver.java:108)
        ... 43 more


Edit 2: Here's a link to the page that's actually generated: index_jsp.html

Any idea? The bean is registered and otherwise working correctly. The method delete exists as well. (The column id's are correct, too)

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Atmocreations
  • 9,923
  • 15
  • 67
  • 102
  • Unrelated to the problem: this won't work on JSF 1.x. Rather use `DataModel#getRowData()` or `f:setPropertyActionListener`. See also [this answer](http://stackoverflow.com/questions/3951263/jsf-command-button-inside-a-jsf-data-table/3951281#3951281). – BalusC Jan 17 '11 at 18:19
  • Please edit your question to fix the syntax errors (which may lead to red herrings) and post as well the entire stacktrace. Then we can post a well suited answer. – BalusC Jan 17 '11 at 18:55
  • Wow... What an illogical concept. That's why these param-tags were for, right? Because if the entire button is outside of the data table, the thing correctly transmits the parameter... :S Will try with the DataModel, thanks! Why the hell didn't you add *this* as the reply? – Atmocreations Jan 17 '11 at 19:03
  • Because this wouldn't have thrown an `IllegalArgumentException`. Please edit your question to include the entire stacktrace. It is likely caused by simething entirely different. As to the illogicalness, the `f:param` is originally intented to add a request parameter to the URL of a `h:outputLink` or `h:commandLink`. This was "fixed" in JSF 2.0 to work in `h:commandButton` as well because of the many "illogical" complaints :) – BalusC Jan 17 '11 at 19:05
  • Thank you. Did you *really* get this when you add just the single line `` and then open the page? In other words, it displays fine when you remove this single line? The stacktrace namely doesn't suggest that at all. It would make a bit more sense if it was *actually* been thrown when you clicked the commandbutton (and the blank space in the EL was indeed not the culprit). – BalusC Jan 17 '11 at 19:16
  • unfortunately and strangely, yes! The page doesn't even seem to render. See the question's body, I added a link to the rendered page. The component tree seems to be fine as well, nothing red. If I remove the param-line, the button and everything else renders just fine. About the space: AFAIK whitespaces don't change anything. That's what the curly brackets are for. – Atmocreations Jan 17 '11 at 19:20

1 Answers1

1

Based on the stacktrace, you're using MyFaces. This might be MyFaces specific, I've never seen this on Mojarra, which I'm already using for years.

At least, using f:param in a h:commandButton wouldn't have worked on JSF 1.x anyway. It works on h:commandLink only. On the other hand, you should be wrapping the datatable's value in a DataModel so that you can obtain the row where the button was pressed. Alternatively, if you're on JSF 1.2, you can also use the f:setPropertyActionListener. You can find examples in this answer.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Found something else: doesn't work with `h:commandLink` either which made me trying to remove the `f:param`-tag again. Still doesn't work. Only if I remove the managed property from `faces-config.xml`, it again displays the table. – Atmocreations Jan 17 '11 at 19:32
  • update: managed to display the link with the param inside the `h:commandLink`, the bean was somehow wrong. Though "`#{item.courseID}`" evaluates to an int, I couldn't have the managed property of type int. This caused the behaviour seen before. The problem now seems that the parameter isn't passed, aborts with another exception. Should I change the question or open a new one? – Atmocreations Jan 17 '11 at 19:43
  • Which exception? Can you ensure that the same datamodel (the object behind the datatable's value) is been served during form submit as it was during initial display? – BalusC Jan 17 '11 at 19:47
  • Gotta check back. It's a managed bean with `request` as scope, this should work because all the values are passed, right? Here the exception: "Error calling action method of component with id j_id_jsp_1372441331_1:j_id_jsp_1372441331_3:8:j_id_jsp_1372441331_42 Caused by: java.lang.NumberFormatException - null" – Atmocreations Jan 17 '11 at 20:02
  • OK, the datamodel is not been preserved. It boils down to that you need to ensure that `#{overviewBean.loadContent}` returns the **same** value during the form submit request. This is answered in detail [here](http://stackoverflow.com/questions/2343493/request-scoped-beans-and-datamodel-initialization). – BalusC Jan 17 '11 at 20:06
  • Changed OverviewBean to session-scoped. Now complaining about `javax.faces.FacesException: Property deleteID references object in a scope with shorter lifetime than the target scope session` The database behind hasn't changed. Well still directly using List as type, not DataModel. Is this a must-have? Finally starting to hate JSF now... – Atmocreations Jan 17 '11 at 20:13
  • It's indeed not possible to inject a request scoped variable during construction of a session scoped bean simply because there can be multiple requests in a session. You need to revise the data loading logic in the request scoped bean or to use `f:setPropertyActionListener` in the session scoped bean instead. Basically, the component tree is rebuilt and reevaluated during the form submit request. One of the reasons is that this prevents CSRF attacks. – BalusC Jan 17 '11 at 20:25
  • Accept: While it was a piece of work, your first comment about DataModel#getRow() did the trick. Accepting this answer that you get the reputation, even though it's not absolutely correct. Thanks a lot! – Atmocreations Jan 17 '11 at 22:58