RE: Can I use a Map.Entry as a bean?
see my comments below... | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Martin Cooper [mailto:[EMAIL PROTECTED]] Sent: Wednesday, January 10, 2001 11:44 PM To: [EMAIL PROTECTED] Subject: Re: Can I use a Map.Entry as a bean? I've done some extensive digging around on this (because I wanted to use inner classes with the Digester as well), and found out what's going on. It's not an inner class thing per se, because I do have inner classes working with the Digester now. First, getValue() is public in both Map.Entry and TreeMap.Entry, so this wasn't affecting things. I assume getKey() is the same, but I haven't checked. What does matter is that Map.Entry is a public inner class, but TreeMap.Entry has only package access. Struts uses bean.getClass() to get the class, and looks up the getter method on that. Not surprisingly, getClass() returns TreeMap.Entry, so that when the getter is found, it is actually the TreeMap.Entry getter, which is not accessible from outside the package. wow! thanks for digging so deep. it's nice to know what's actually going on. What this tells us (I think) is that the PropertyUtils introspection code won't work on a bean whose concrete class is not public, even if it is derived from, and almost exclusively manipulated as, a public interface. One interesting point that I discovered on my trails through the code is that the "type" attribute on the logic:iterate tag does not appear to be used at all. It certainly isn't taken into account when bean:write is doing its thing. This actually makes sense when you think about it - the logic:iterate tag just puts a bean into the requested scope, and it's up to the retriever (in this case, bean:write) to decide what type it is. why is the type attribute even in the iterate tag then? just curious... OK, so much for the problem. What can we do about it? Well, in theory, we could add a "type" attribute to bean:write, and then have that passed through to where the introspection happens. The problems I see with this are that bean:write is undoubtedly not the only tag that would have to be modified to handle this, and that a pile of code would have to change so that the type can wend its way down to the appropriate introspection code. The only other alternative I can think of is a bit hairy. That would be to have the introspection code first figure out whether a method is accessible (by looking at the modifiers of the method and its class). If the method is not accessible, then the code would work its way down through the base classes and implemented interfaces to look for an accessible version, and use the corresponding class to call the method. Like I said, a bit hairy. On the other hand, we could just do nothing. I would assume that this is not something a lot of people will hit, and that Chris is just one of those unlucky folks. :-} true... however, why is there even the ability to work with maps in this way with the iterate tag then? 1) simply so i can use scriptlets to get at the values of the entries? if i'm going to use scriptlets, i might as well just use scriptlets to iterate as well. 2) or in the hope that someone will implement a map that doesn't use a protected map.entry class? the only reason i can see to fix it, is so that the working of the struts iterate tag is consistent. if i can't get at the stuff with tags, it's confusing to iterate it with tags (in the case of maps). i've since worked around this by basically stuffing my own 'entry-like' class in a set which works great, except that it doesn't work like a map when querying, only with iterating. maps are handy for building select lists and such and then getting the indexed value in a servlet somewhere instead of having to iterate through an entire set. i actually agree that it's probably not a big enough deal to fix or contend with, i'm just a consistency freak :) thanks for the help and info! struts rocks, chris -- Martin Cooper Tumbleweed Communications - Original Message - From: "Craig R. McClanahan" [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Tuesday, January 09, 2001 12:32 PM Subject: Re: Can I use a Map.Entry as a bean? Chris Wilson wrote: here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! I did some playing with this as well. It seems to be a Java API issue -- Map.Entry is an inner class, so apparently Java reflection APIs are not allowed to call it's methods dynamically (the way that the Struts tags need to in order to be generalized :-(. As you noted, using mapEntry.getKey() and mapEntry.getValue() directly seems to work, so we could cheat if need be -- but I would hate to start special casing the code in bean:write (and all
Re: Can I use a Map.Entry as a bean?
At 09:57 AM 1/11/01 -0800, you wrote: Chris Wilson wrote: From: Martin Cooper [mailto:[EMAIL PROTECTED]] [snip] One interesting point that I discovered on my trails through the code is that the "type" attribute on the logic:iterate tag does not appear to be used at all. It certainly isn't taken into account when bean:write is doing its thing. This actually makes sense when you think about it - the logic:iterate tag just puts a bean into the requested scope, and it's up to the retriever (in this case, bean:write) to decide what type it is. why is the type attribute even in the iterate tag then? just curious... Check out the org.apache.struts.taglib.logic.IterateTei class -- you will see that the "type" attribute is used to define the Java data type of the scripting variable that is exposed to the page. This does not generally matter if you only access the exposed bean with custom tags, but does matter if you try to access it with scriptlets -- the default data type is java.lang.Object, so you would have to cast all your method calls. The same general pattern is followed in other places where the "type" attribute is used for the same purpose, such as bean:define. Craig Ah, the TEI is one of the pieces of custom tags that I'm not up on quite yet. I was looking for code that called getType() or setType(), and I couldn't find any, which is how I came to my (incorrect) conclusion. It did seem odd that the field would be there but not used at all. ;-) -- Martin Cooper Tumbleweed Communications
RE: Can I use a Map.Entry as a bean?
yeah, i tried that too. no difference... thanks though, chris | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Martin Cooper [mailto:[EMAIL PROTECTED]] Sent: Wednesday, January 10, 2001 1:16 AM To: [EMAIL PROTECTED] Subject: Re: Can I use a Map.Entry as a bean? Just a thought, but have you tried "java.util.Map$Entry" instead of "java.util.Map.Entry" when you specify the type? -- Martin Cooper Tumbleweed Communications - Original Message - From: "Chris Wilson" [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Tuesday, January 09, 2001 12:00 PM Subject: RE: Can I use a Map.Entry as a bean? here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ## | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use the iterate tag with a TreeMap and the write tag... here's a snippet of my code: logic:iterate na
Re: Can I use a Map.Entry as a bean?
I've done some extensive digging around on this (because I wanted to use inner classes with the Digester as well), and found out what's going on. It's not an inner class thing per se, because I do have inner classes working with the Digester now. First, getValue() is public in both Map.Entry and TreeMap.Entry, so this wasn't affecting things. I assume getKey() is the same, but I haven't checked. What does matter is that Map.Entry is a public inner class, but TreeMap.Entry has only package access. Struts uses bean.getClass() to get the class, and looks up the getter method on that. Not surprisingly, getClass() returns TreeMap.Entry, so that when the getter is found, it is actually the TreeMap.Entry getter, which is not accessible from outside the package. What this tells us (I think) is that the PropertyUtils introspection code won't work on a bean whose concrete class is not public, even if it is derived from, and almost exclusively manipulated as, a public interface. One interesting point that I discovered on my trails through the code is that the "type" attribute on the logic:iterate tag does not appear to be used at all. It certainly isn't taken into account when bean:write is doing its thing. This actually makes sense when you think about it - the logic:iterate tag just puts a bean into the requested scope, and it's up to the retriever (in this case, bean:write) to decide what type it is. OK, so much for the problem. What can we do about it? Well, in theory, we could add a "type" attribute to bean:write, and then have that passed through to where the introspection happens. The problems I see with this are that bean:write is undoubtedly not the only tag that would have to be modified to handle this, and that a pile of code would have to change so that the type can wend its way down to the appropriate introspection code. The only other alternative I can think of is a bit hairy. That would be to have the introspection code first figure out whether a method is accessible (by looking at the modifiers of the method and its class). If the method is not accessible, then the code would work its way down through the base classes and implemented interfaces to look for an accessible version, and use the corresponding class to call the method. Like I said, a bit hairy. On the other hand, we could just do nothing. I would assume that this is not something a lot of people will hit, and that Chris is just one of those unlucky folks. :-} -- Martin Cooper Tumbleweed Communications - Original Message - From: "Craig R. McClanahan" [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Tuesday, January 09, 2001 12:32 PM Subject: Re: Can I use a Map.Entry as a bean? Chris Wilson wrote: here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! I did some playing with this as well. It seems to be a Java API issue -- Map.Entry is an inner class, so apparently Java reflection APIs are not allowed to call it's methods dynamically (the way that the Struts tags need to in order to be generalized :-(. As you noted, using mapEntry.getKey() and mapEntry.getValue() directly seems to work, so we could cheat if need be -- but I would hate to start special casing the code in bean:write (and all the other tags that can access properties) for wierd situations like this ... Craig i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" propert
RE: Can I use a Map.Entry as a bean?
here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ## | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use the iterate tag with a TreeMap and the write tag... here's a snippet of my code: logic:iterate name="subjects" id="subjectEntry" scope="request" type="java.util.Map.Entry" // subjects is a TreeMap in the request object... no problem there // it's my understanding that when the iterate tag is used with a map, the // iterator is on the Set of Map.Entries returned by Map.entitySet(), // therefore the object exposed as subjectEntry should be a java.util.Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this is where i get an IllegalAccessException attempting to access the //property value of subjectEntry, even though there is a getValue() method in the //api... /logic:iterate just for fun, i replaced the write tag above with the following scriptlet which i believe is logically equivalent: %= ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).getValue( ) % and that works!
RE: Can I use a Map.Entry as a bean?
Chris, I'm receiving the same error with an application that's not using struts. It does use a custom tag however. The application ran perfectly on NT and I haven't changed a thing, but now I'm getting the same error as you when I run it on an HP-UX box. Other jsp pages run fine, but when I hit a custom tag, then I get this error. I could be way off, but I'm pretty sure it's because I have an incorrect file or directory permission somewhere. Sadly, I haven't had a chance to troubleshoot it yet. Anyways, you may want to look at file and directory permissions, as it could be the cause of the problem. Do other custom tags work except for this one, or is it all custom tags? If you discover the solution, I would love to know. Perry Tew -Original Message- From: Chris Wilson [SMTP:[EMAIL PROTECTED]] Sent: Tuesday, January 09, 2001 3:01 PM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ## | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use
Re: Can I use a Map.Entry as a bean?
Chris Wilson wrote: here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! I did some playing with this as well. It seems to be a Java API issue -- Map.Entry is an inner class, so apparently Java reflection APIs are not allowed to call it's methods dynamically (the way that the Struts tags need to in order to be generalized :-(. As you noted, using mapEntry.getKey() and mapEntry.getValue() directly seems to work, so we could cheat if need be -- but I would hate to start special casing the code in bean:write (and all the other tags that can access properties) for wierd situations like this ... Craig i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ## | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use the iterate tag with a TreeMap and the write tag... here's a snippet of my code: logic:iterate name="subjects" id="subjectEntry" scope="request" type="java.util.Map.Entry" // subjects is a TreeMap in the request object... no problem there // it's my understanding that when the iterate tag is used with a map, the // iterator is on
RE: Can I use a Map.Entry as a bean?
see my comments below... | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]] Sent: Tuesday, January 09, 2001 3:32 PM To: [EMAIL PROTECTED] Subject: Re: Can I use a Map.Entry as a bean? Chris Wilson wrote: here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! I did some playing with this as well. It seems to be a Java API issue -- Map.Entry is an inner class, so apparently Java reflection APIs are not allowed to call it's methods dynamically (the way that the Struts tags need to in order to be generalized :-(. i suspected that might be the case... As you noted, using mapEntry.getKey() and mapEntry.getValue() directly seems to work, so we could cheat if need be -- but I would hate to start special casing the code in bean:write (and all the other tags that can access properties) for wierd situations like this ... i agree, i wouldn't advocate hacking struts to 'fix' special cases like this. interestingly enough, the jsp:getProperty ... / tag fails in the same way. oh well... i will work around it. just wanted to make sure i wasn't crazy/doing something wrong. cheers! Craig i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ## | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more trouble
Re: Can I use a Map.Entry as a bean?
Just a thought, but have you tried "java.util.Map$Entry" instead of "java.util.Map.Entry" when you specify the type? -- Martin Cooper Tumbleweed Communications - Original Message - From: "Chris Wilson" [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Tuesday, January 09, 2001 12:00 PM Subject: RE: Can I use a Map.Entry as a bean? here's a simple example of what i'm talking about. would one of your wizards please try this servlet and jsp page to see what i'm talking about? thanks very much! i tried this on tomcat 3.2.1, jdk 1.3, win 2000 ## Begin TestServlet.java ## import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.util.HashMap; import java.io.IOException; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HashMap map = new HashMap(); map.put("test", "hope this works"); map.put("foo", "bar"); req.setAttribute("map", map); getServletContext().getRequestDispatcher("/display.jsp").forward( req, res); } } ## End TestServlet.java ## ## Start display.jsp ## %@ taglib uri="struts-logic.tld" prefix="logic" % %@ taglib uri="struts-bean.tld" prefix="bean" % html head titledisplay.jsp/title /head body logic:iterate name="map" id="entry" scope="request" type="java.util.Map.Entry" !-- i get an IllegalAccessException when running the following two lines -- !-- delete the following two lines to elimate the IllegalAccessException -- bean:write name="entry" property="key" scope="page" / - bean:write name="entry" property="value" scope="page" /br !-- why dosen't this work? -- !-- end delete -- !-- these two lines work! they don't throw an exception -- !-- they are functionally equivelent to the above two lines right? -- %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getKey() % - %= ((java.util.Map.Entry)pageContext.getAttribute("entry")).getValue() %br /logic:iterate /body /html ## End display.jsp ###### | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Chris Wilson [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:46 AM To: [EMAIL PROTECTED] Subject: RE: Can I use a Map.Entry as a bean? yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).get Value() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use the iterate tag with a TreeMap and the write tag... here's a snippet of my code: logic:iterate name="subjects" id="subjectEntry" scope="request" type="java.util.Map.Entry" // subjects is a TreeMap in the request object... no problem there // it's my understanding that when the iterate tag is used with a map, the // iterator is on the Set of Map.Entries returned by Map.entitySet(), // therefore the object exposed as subjectEntry should be a java.util.Map.Entry bean:write name="subje
RE: Can I use a Map.Entry as a bean?
yes, i've included both taglib defs... in fact, the tags are working great. it's only the write tag that's having a problem, and only when i try to get a property on a Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this fails with an IllegalAccessException... ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).getValue() // this works! if i use my own bean in the write tag, everything is dandy. it's just the dang Map.Entry! | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | | -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, January 04, 2001 10:11 AM To: Struts List Subject: Re: Can I use a Map.Entry as a bean? So, you've included the Struts bean tag library along with logic, yes? %@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" % %@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" % You can get some weird and misleading error messages if you omit a taglibs you're using. The inner class shouldn't cause a problem, since the iterate tag is designed for that (an attribute or property of an attribute). For more troubleshooting, did you try setting the inner class as a standalone page attribute, to see if that works too? *** REPLY SEPARATOR *** On 1/4/2001 at 9:17 AM Chris Wilson wrote: hello, sorry to post this similar message again, but i'm really stumped... i've run into a problem however trying to use the iterate tag with a TreeMap and the write tag... here's a snippet of my code: logic:iterate name="subjects" id="subjectEntry" scope="request" type="java.util.Map.Entry" // subjects is a TreeMap in the request object... no problem there // it's my understanding that when the iterate tag is used with a map, the // iterator is on the Set of Map.Entries returned by Map.entitySet(), // therefore the object exposed as subjectEntry should be a java.util.Map.Entry bean:write name="subjectEntry" property="value" scope="page" / // this is where i get an IllegalAccessException attempting to access the //property value of subjectEntry, even though there is a getValue() method in the //api... /logic:iterate just for fun, i replaced the write tag above with the following scriptlet which i believe is logically equivalent: %= ((java.util.Map.Entry)pageContext.getAttribute("subjectEntry)).getValue( ) % and that works! of course, i could simply use this scriptlet and my problem would be solved, but i'd like to use only taglibs if possible and it seems to me that the bean:write tag should do the same thing... will bean:write only work on "bean-like" objects that are public? in this case the object implementing the Map.Entry interface is an inner class in TreeMap. is that causing the problem? what am i missing? thanks for any help! cheerio, chris | chris wilson || web dev ||| [EMAIL PROTECTED] || | www.wondergeek.com | |