DynamicBeanMap

Previously I posted about using the atg.beans.DynamicBeanMap class to wrap a RepositoryItem so that it is accessible via JSTL.  However it turns out this is not a great solution.

If we want to access a simple property in a RepositoryItem wrapped in a DynamicBeanMap it is relatively straightforward.  For example,

${user.name}

However if we want to access a RepositoryItem property like this,

${user.address}

then we end up getting a StackOverflowError as the DynamicBeanMap spins going back forth between the user RepositoryItem and the address RepositoryItem.

Interestingly enough accessing a simple property from the RepositoryItem property works fine.

${user.address.city}

One solution is to set the recursive argument to false when creating the DynamicBeanMap.

DynamicBeanMap itemBean = new DynamicBeanMap(pValue, false);

When you do this the following will work correctly.

${user.address}

However this no longer works.

${user.address.city}

We ended up abandoning the DynamicBeanMap and creating a library of strongly typed repository item wrapper proxy objects.

ATG Support helped me tremendously to figure out what was going on. They suggested an alternative which we never tried because of the large impact it would have on our JSP.

What I determined in looking at this further is that the DynamicBeanMap class is not really documented for customer use, but there is a DSP/DSPEL tag called “tomap” that uses this class that we do document. See the appendix in our 2006.3 Page Developer’s guide.

So, this tag would avoid this problem since it does have an undocumented “recursive” attribute that defaults to “false”, but I think it might be preferable to set it to “true” and use another undocumented option. After using the “tomap” tag with recursive=true, you can then use a _realObject property to unwrap your “final” object being accessed.

So if your tag is:

<dspel:getvalueof var="address" param="user.address" />

You can change it to use:

<dspel:getvalueof var="address" param="user.address._realObject" />

Or if you were doing:

<dspel:valueof param="user" />

you could use:

<dspel:valueof param="user._realObject" />

Basically you just unwrap whatever end/final object you’re trying to get to with _realObject.  Since we can’t see exactly what code called hashCode that caused the StackOverflowError, I can’t be certain this will avoid the StackOverflowError, but I suspect it will.

This solution will have the benefit of having minimal impact on your ability to access properties with JSTL.

I’ve entered a PR #155848 about some of these properties not being documented.

Also PR #81771 was submitted requesting the ability to recursively access repository items in JSTL.

Leave a Reply

Your email address will not be published. Required fields are marked *