Evaluating attributes in custom tags
Hi,
I have a piece of code that i know used to work, but now seems to be throwing exceptions.
I was using the ExpressionEvaluatorManager to retrieve an object passed as an attribute in a tag like this
Content mgnlContent = (Content)ExpressionEvaluatorManager.evaluate("content", content,
Content.class, this, pageContext);
using this tag in my jsp file
<inf_mgnl:out content="${result}" node="linkTitle" />
The error i am getting is this
javax.servlet.jsp.JspException: An error occurred while evaluating custom
action attribute "content" with value "info.cms.core.Content[/ap/news/
US-grants-Merial-conditional-approval-for-Canine-Melanoma-Vaccine0]": Attempt to
convert String "info.cms.core.Content[/ap/news/US-grants-Merial-condit
ional-approval-for-Canine-Melanoma-Vaccine0]" to type "info.cms.core.Co
ntent", but there is no PropertyEditor for that type (null)
Does anybody have an idea where i am going wrong here?
Dieter
[1111 byte] By [
lehmannda] at [2007-11-27 2:09:15]

# 1
The error may be in how you assign a value to the result variable. It looks like you are assigning a String with the name of the class, and not an instance of the class itself (probably a toString() method call).So look to where you assign result and fix that.
# 2
Yes, i was thinking that, but if I'm interpreting your answer correctly, the value of result is not a string as i can retrieve other variables from the object.
The ExpressionEvaluatorManager is definitely trying to convert a toString() output to a Content object. My issue is how to stop it doing that.
Dieter
# 3
When can you get other values from it? In the inf_mgnl tag? Any other tag or anyplace AFTER you assigned whatever the object is to the result variable? What does: <% pageContext.findAttribute("result").getClass().toString() %> give you?
# 4
No, I can get other values from it prior to the inf_mgnl tag. But yes, i cant retrive values from the bean after i have assigned it to the result variable.
<% pageContext.findAttribute("result").getClass().toString() %>
gives me
class info.cms.core.Content
# 5
Okay, so you do have an object of type Content.class in the result object.
What server and version are you using?
My guess:
You have a JSP 2.0 type server (Tomcat 5 or better perhaps) with EL Expression language turned on. So the EL language is translated at the JSP level, passing you an object instead of a String. You then are using the expression manager to try and re-translate, which expects a String so turns the object into a string via toString.
If this is the case, you have to choose which you want to do:
1) Take advantage of the JSP functionality and change the way the custom tag accepts areguments. One option would be to test what type the content parameter is. If it is a String, use the expression manager, otherwise use the passed in object. For example:
public class TagHandlerName ... {
private Object contentObject;
public void setContent(Object content) {
this.contentObject = content;
}
public int doStartTag() {
Content mgnlContent = null;
if (contententObject instanceof Content.class) {
mgnlContent = (Content)contentObject;
} else {
mgnlContent = (Content)ExpressionEvaluatorManager.evaluate("content", content,
Content.class, this, pageContext);
}
So if the server parses EL, you get a class of type Content, and you don't have to pass it through the expression evaluator.
The second option would be to make the JSP backwards compatible. So either use the old web.xml version number, or using the isELIgnored page directive at the top of the JSP
<%@ page isELIgnore="true" %>
Or as a default setting in the jsp-config configuration of your web.xml
<web-app ...>
...
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
So it depends on what you would rather do, edit the tag or constrain the JSPs.
# 6
Yes you are right, i am using Tomcat 5.x server.
I would ideally like to use the first option as i am enjoying th features of the expression language turned on. I did try your first option, but still ran into difficulties.
org.apache.jasper.JasperException: javax.servlet.jsp.JspException: ServletExcept
ion in '/docroot/ap/tiles/searchResultsItem.jsp': com.web.tagli
b.ContentAttributeDisplayTag.setContent(Ljava/lang/String;)V
It seems that it still does not like the String being passed through
# 7
MicroNova YUZU tag libary (https://micronova-yuzu.dev.java.net) accepts non-String objects using code like yours, but attributes are declared with rtexprvalue=true in the TLD even for JSP 2.0. If you don't already have this in your TLD, it might be worth a try. Hope this helps.
# 8
You have to update the tag library descriptor (the .tld) to have the <rtexprvalue>true</rtexprvalue> tag for the content attribute, and make sure the setContent method has the signature:
public void setContent(Object content)
Finally, after making those changes, restart the server so you know you are working with the current version of the tag
# 9
Thanks, i appreciate all your help.This is exactly the setup i have in my application :( and it doesnt work.Any ideas where i am going wrong? Should i supply more code..