Mysterious dspel:include problem with flush=true

When I use dspel:include within a custom tag like below things work fine.

<betweengo:link href="/click.do?id=foo"><dspel:include
page="/include/bar.jsp"/></betweengo:link>

However when I add flush=”true” it fails silently.

<betweengo:link href="/click.do?id=foo"><dspel:include
page="/include/bar.jsp" flush="true"/></betweengo:link>

The JSP page no longer renders after it gets to this line of code.  What puzzles me even more is that the documentation says that if you do not explicitly set flush, flush happens automatically.  Therefore theoretically adding flush=”true” should not have an effect though I do it because the documentation recommends doing it.

The above code is happening within a TargetingForEach droplet.  It is running on an ATG 2006.3 Patch 2 app server with JBoss 4.0.4.GA.

I contacted ATG support about this issue and they responded very quickly.  Basically they said don’t use flush=”true” on third party application servers and just rely on the automatic flush.

Entered on 07/29/2008 at 13:12:19 by Nicholas Glover:
Hi Frank,

You should note that JBoss 4.0.4 GA is not supported with any version of ATG and you should not be using it. Please stick with JBoss 4.0.3 SP1.

Also, it is imperative that you upgrade from your ATG version to the latest 2006.3 patch, patch 6. The latest patch has many bugfixes include a fix for one relating to flushing behavior, PR #134387.

Due to various bugs and issues encountered, use of the “flush” attribute with a 3rd party app server, is not really recommended. We are removing all docs for this feature in later versions of our documentation. In this case, flush=true is forcing an explicit flush on the current page; but if this is not set, a more “intelligent” auto flush is done that flushes top-level pages first and then progresses down the tree. This prevents problems with 3rd party app servers such as content getting rendered out of order. I recommend not messing with the “flush” setting.

Is there something you are trying to do that is not working that leads you to want to use the “flush” attribute?

Thanks.


Nick Glover
ATG Support

Entered on 07/29/2008 at 15:02:57 by Nicholas Glover:
Hi Frank,

I had already entered the documentation bug about this previously, but I polished and published it for our site with what I learned when looking into this for a prior customer and when looking into it for you.

It is PR #146637. Here’s the link:
http://www.atg.com/esupport/bugs/index.jsp?FullViewBug=ViewBug&bugId=146637

I’ll close this case now.

Thanks.


Nick Glover
ATG Support

Fixing IllegalArgumentException in ACC

Recently I was unable to create an item using the ACC because of an IllegalArgumentException.

java.lang.IllegalArgumentException:  Attempt to set
property named view (ContentList:800007)  with value =
moduleTemplate:2200004 (class=class atg.adapter.gsa.GSAItem).
This property  failed due to a property type specific test.
Enable loggingDebug for  details.

It turned out to be a simple issue of the wrong case. The repository path for the ContentList view item was:

/Betweengo/repository/Portal

when it should have been

/betweengo/repository/Portal.

This is certainly not obvious from the exception.

TargetingRange ignoring start param

We were using the TargetingRange droplet to display a number of slides, starting with the 2nd slide.  We would never show more than 9 slides so we set howMany to 9.

What we found was that the TargetingRange droplet was always returning all the slides, including the first slide, no matter what we set for start.

Fortunately ATG support identified this problem as Bug #84551.  If the howMany param > number of targets returned then it ignores the start position parameter.

The work around is to make sure to set the howMany parameter to the number of items you expect.

Jumping to different parts of a page using a dropdown

It is relatively simple to dynamically create a dropdown from which you can jump to different parts of a page using JavaScript and ATG DSPEL.

First create the dropdown.

<form name="jumpTo" action=".">
  <dspel:droplet name="/atg/dynamo/droplet/ForEach">
    <dspel:param name="array" param="categories"/>
    <dspel:setvalue param="category" paramvalue="element"/>
    <dspel:oparam name="outputStart">
      <select name="names">
    </dspel:oparam>
    <dspel:oparam name="output">
      <dspel:getvalueof id="index" param="index"/>
      <c:set var="catShortName" value="cat${index}"/>
      <option value="<c:out value="${catShortName}"/>">
        <dspel:valueof param="category.name"/>
      </option>
    </dspel:oparam>
    <dspel:oparam name="outputEnd">
      </select>
    </dspel:oparam>
  </dspel:droplet>
</form>

Next create the button outside of the form for jumping to different parts of the page. I learned about the window.location.hash from this article. And I learned about how to access the selected value from the dropdown from this article.

 <input type="image" src="/img/buttons/update.gif"
   onClick="window.location.hash=
document.jumpTo.names.options[document.jumpTo.names.selectedIndex].value">

Finally you create the name anchors throughout your document.

<dspel:droplet name="/atg/dynamo/droplet/ForEach">
  <dspel:param name="array" param="categories"/>
  <dspel:setvalue param="category" paramvalue="element"/>
  <dspel:oparam name="output">

    <%-- magazine category --%>
    <dspel:getvalueof id="index" param="index"/>
    <c:set var="catShortName" value="cat${index}"/>
    <a name="<c:out value="${catShortName}"/>"
       id="<c:out value="${catShortName}"/>">
      <dspel:valueof param="category.name"/>
    </a>

  </dspel:oparam>
</dspel:droplet>

Log SQL on ATG

Dudley Zoo Sarah the Sumatran Tiger (Life Of Pi) on FlickrDudley Zoo Sarah the Sumatran Tiger (Life Of Pi) by donebythehandsofabrokenartist

To log SQL turn on logging debug for your Repository component.

For example, set /betweengo/repository/Repository.loggingDebug to true.

Note that a lot of SQL statements are outputted. If you want to selectively turn it on and off you can put this in your JSP where you want to start logging SQL.

<dspel:setvalue bean="/betweengo/repository/Repository.loggingDebug"  value="true"/>

And then put this in your JSP where you want to stop logging SQL.

<dspel:setvalue bean="/betweengo/repository/Repository.loggingDebug"  value="false"/>

Note I think this solution only works if you are using a javax.sql.DataSource like in a JBoss configuration.

For ATG’s atg.service.jdbc.FakeXADataSource there are special properties for logging SQL.

Property Description
loggingSQLError logs SQL exceptions as errors
loggingSQLWarning logs SQL warnings received by the pool
loggingSQLInfo logs SQL statements sent by the pool
loggingSQLDebug logs JDBC method calls made by the pool

For debugging purposes most of the time you will just want to set loggingSQLInfo=true.

For further reading please see Configuring ATG Data Sources for Data Import in the ATG Installation and Configuration Guide.

Content Repository in ACC

To display a content repository in the ACC it must be listed in the initialRepositories property of the /atg/registry/ContentRepositories component.

For example:

initialRepositories+=\
       /betweengo/repository/Portal

From the ATG Repository Guide > 12. SQL Repository Reference > Configuring the SQL Repository Component > Registering a Content Repository:

Content repositories must be added to the list of repositories in the initialRepositories property of the /atg/registry/ContentRepositories component. This also causes the new repository to show up in the Content window of the ATG Control Center.

Droplet Name Case Sensitivity

In one of our JSP files we included a droplet like this:

<dspel:droplet name="/betweengo/droplet/foo">

However the actual properties file is named Foo.properties. On Windows this was not an issue because Windows file system is case insensitive but when we moved to UNIX we saw this exception:

javax.servlet.jsp.JspException:  CANT_FIND_DROPLET: Unable to find the droplet with name  "/betweengo/droplet/foo"

This is not surprising since UNIX’s file system is case sensitive. Once we corrected the capitalization ATG was able to locate the droplet.

URLHammer

URLHammer is a simple tool from ATG for doing load and performance testing.

Here is an example of using it.

E:\>cd ATG\ATG2006.3\DAS\lib

E:\ATG\ATG2006.3\DAS\lib>set CLASSPATH=classes.jar

E:\ATG\ATG2006.3\DAS\lib>java atg.core.net.URLHammer
http://localhost:8080/test.jhtml 10 100 -cookies

Time = 110068 ms   (9.09 requests/s; average latency = 1101 ms)
0 errors out of 1000 requests

Sorting Nested Properties

ATG’s looping droplet have the nice ability of sorting nested properties. For example say you have a repository item Person and it has a property address which is a repository item Address and you want to sort on the address’s street. Then you can do something like this.

<dspel :param name="sortProperties" value="+address.street"/>

ATG does this through the magic of DynamicBeans.

ATG Parameter Names

Often in ATG form handler or droplet code one finds code like this:

public static final String OUTPUT = "output";

You can take advantage of ATG’s ParameterName class to represent any parameter name. From the ATG 2006.3 API Reference:

A ParameterName object can represent any parameter name used in Dynamo. Use this class when building your own droplets to create unique parameter names. The parameter names will then be stored in a global hashtable keyed by strings. Using this class allows the parameters of a droplet to be publicly available as well as enforcing good coding standards whereby the parameter name string only appears once in the java code.

Throughout ATG’s public source you can see that many parameter names have already been defined. For brevity sake I have omitted the “public final static” prefix.

ParameterName ARRAY = ParameterName.getParameterName("array");
ParameterName DEBUG = ParameterName.getParameterName("debug");
ParameterName DEFAULT = ParameterName.getParameterName("default");
ParameterName ELEMENT_NAME = ParameterName.getParameterName("elementName");
ParameterName EMPTY = ParameterName.getParameterName("empty");
ParameterName EQUAL = ParameterName.getParameterName("equal");
ParameterName GREATERTHAN = ParameterName.getParameterName("greaterthan");
ParameterName INDEX_NAME = ParameterName.getParameterName("indexName");
ParameterName IN_URL = ParameterName.getParameterName("inUrl");
ParameterName LESSTHAN = ParameterName.getParameterName("lessthan");
ParameterName NONCOMPARABLE = ParameterName.getParameterName("noncomparable");
ParameterName NON_SECURE_URL = ParameterName.getParameterName("nonSecureUrl");
ParameterName OBJ1 = ParameterName.getParameterName("obj1");
ParameterName OBJ2 = ParameterName.getParameterName("obj2");
ParameterName OUTPUT = ParameterName.getParameterName("output");
ParameterName OUTPUT_END = ParameterName.getParameterName("outputEnd");
ParameterName OUTPUT_START = ParameterName.getParameterName("outputStart");
ParameterName PATH = ParameterName.getParameterName("path");
ParameterName REVERSE_ORDER = ParameterName.getParameterName("reverseOrder");
ParameterName SECURE_URL = ParameterName.getParameterName("secureUrl");
ParameterName SORT_PROPERTIES = ParameterName.getParameterName("sortProperties");
ParameterName TRUE  = ParameterName.getParameterName("true");
ParameterName UNSET = ParameterName.getParameterName("unset");
ParameterName VALUE = ParameterName.getParameterName("value");
ParameterName CURRENCY_PARAM = ParameterName.getParameterName("currency");
ParameterName EURO_SYMBOL_PARAM = ParameterName.getParameterName("euroSymbol");
ParameterName LOCALE_PARAM = ParameterName.getParameterName("locale");
ParameterName TARGET_LOCALE_PARAM = ParameterName.getParameterName("targetLocale");
ParameterName YEN_SYMBOL_PARAM = ParameterName.getParameterName("yenSymbol");