This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.

Title

Missing ognl?

Description

<n>This article was originally published on the <a href="http://blogs.encodo.ch/news/view_article.php?id=19"><b>Encodo Blogs</b></a>. Browse on over to see more!</n> <hr> Every once in a while, when adding a new component to or changing an existing one on a Tapestry page, you'll make a mistake. Most of the time, the exception handler page is pretty good; sometimes the exception can be quite confusing. For example, suppose we have a custom component with a single property: <code> package com.encodo.blogs.samples; class CustomComponent extends BaseComponent { public abstract SomeObject getCustomParameter(); } </code> To use this component in a page, you just write the following: <code> </code> This <i>looks</i> ok<fn>, but when loaded in a browser causes the following error: <div class="error"><c>org.apache.tapestry.BindingException</c> Error converting value for template parameter customParameter: No type converter for type <c>com.encodo.blogs.samples.SomeObject</c> is available.</div> With this kind of error message, you're ready to start imagining all sorts of horrible things: <ul> Is something declared with the wrong type? No ... there's no type declaration for properties; Tapestry reads the type from the class field. Is there a data squeezer problem? Is this class not supported? Does it need to be <c>Serializable</c>? Is Tapestry trying to store persist the property to the session or cookie? Not likely, but who knows? </ul> The missing magic in the above example is <c>ognl:</c>. Tapestry uses the <a href="http://www.ognl.org/">Object-Graph Navigation Language</a> to process references to Java code in its templates and page/component definitions. However, the default for HTML attributes is <c>literal:</c>, which performs no extra processing. Since <c>ognl:</c> is missing, <c>obj</c> is simply a string, which Tapestry cannot convert to <c>SomeObject</c>. To fix the problem, just add <c>ognl:</c> before the object reference, like this: <code> <span class="highlight">ognl:</span>obj"/> </code> This being such a common error, it would be nice if Tapestry could do some common-sense handling of it to help emit a better message. One simple way is to specify what, exactly, it was trying to convert to the target object. Compare to the following error message: <div class="error"><c>org.apache.tapestry.BindingException</c> Error converting <span class="highlight">"obj" (interpreted as "literal:obj")</span> for template parameter customParameter: No type converter for type <c>com.encodo.blogs.samples.SomeObject</c> is available.</div> Once the developer sees how Tapestry interpreted the component declaration, it's much easier to pinpoint the error. Now, for purely asthetic reasons, let's make this message more user-friendly: <div class="error"><c>org.apache.tapestry.BindingException</c>: The value for template parameter "customParameter", given as "obj" and interpreted as "literal:obj", could not be converted to <c>com.encodo.blogs.samples.SomeObject</c>.</div> That error message, at least, should no longer inspire panic and desperate restarts of the testing server. <hr> <ft>Unless you're an old Tapestry hand and have already spotted the error, in which case you should be <i>writing</i> these tips, not <i>reading</i> them.</ft> <n>Using Java 1.5</n>