Don’t always use GenericService

Sorry... what exactly is in this can again?

Sorry… what exactly is in this can again? by Paul Jerry, on Flickr

This is the most common thing you will see in an ATG Java class.

public class Foo extends GenericService

However 90% of the time it is extending GenericService so that the class has access to ATG’s logging capabilities.

This is overkill. The GenericService is much more than a logging service. As its name suggests it is meant to be extended by services, typically globally scoped. The main reason to extend GenericService is to get access to methods for controlling the service like doStartService and doStopService.

If you just want logging instead extend ApplicationLoggingImpl. It’s lighter weight and it’s clear why you are extending it. The only caveat is you have to remember to set the loggingIdentifier property in the properties file. For example:

# /betweengo/Foo

Another advantage of using ApplicationLoggingImpl is that the source is available in DAS/src/Java in the ATG installation unlike with GenericService.

Hopefully some people will read this post and on my next consulting project I won’t see such egregious uses of GenericService. Smile

Why is there a _requestid in my URL?

Sometimes when you are using an ATG powered website, e.g. Keds, you will see a _requestid parameter in your URL, e.g.

This occurs when the ATG code, typically a form handler, does a local redirect instead of a redirect. This is ATG’s own flavor of redirect which does a few extra things as described in the JavaDoc:

Sends a redirect response to the client using the specified redirect location URL. This function is similar to sendRedirect(), with the following two differences:

  • The session ID is added to the URL if a valid cookie with the session ID is not found.
  • If the URL is a relative URL (i.e., “login/error.html”), then the URL will be converted to a full absolute URL, as required by the HTTP specification. A relative URL is one that does not specify a protocol (e.g., “http:”).

In general, this function should be used when redirecting back to a page on the same site. If you are redirecting to a page on some other site, use the full absolute URL and call sendRedirect().

However this does not explain the mysterious _requestid parameter. Fortunately ATG’s Programming Guide does:

Preserving Request Scoped Objects on Redirects

If a request results in a redirect to a local page through the method HttpServletResponse.sendLocalRedirect(), the ATG platform treats the redirect request as part of the original request, and maintains any request-scoped objects associated with that request. To implement this, the ATG platform adds an additional query parameter named _requestid to the redirected URL.

Now you know what the _requestid parameter is and why it exists. And if you don’t want it then you the programmer should use a redirect instead of a local redirect.

Load ATG Order

Crystal Ball | FlickrCrystal Ball by David Reece

You can always look up an order in the repository using it’s ID.  But then you want to use the properties of this order object you will always be calling getPropertyValue and casting it to the type you expect.

A better and much simpler way is to look up the order using the OrderManager.  Then you get a strongly typed Order object and don’t have have to deal with the repository.  Life has become a little easier. 🙂

OrderManager orderManager = getOrderManager;
Order order = orderManager.loadOrder(orderId);

Now that you have the order you can also get the profile for that order.

RepositoryItem profile = getProfileTools().getProfileForOrder(order);

Combining XML in ATG

250/365 - Bricks

(Photo: 250/365 – Bricks by Kenny Louie)

ATG uses XML files sometimes instead of Java properties files for configuration. Combining them is not as straight-forward as with Java properties files but more flexible.

The XML File Combination section in the Nucleus: Organizing JavaBean Components chapter of the ATG Programming guide gives a good explanation. You can combine XML files using one of these methods.

  • replace
  • remove
  • append
  • append-without-matching
  • prepend
  • prepend-without-matching

In most cases you will append which is what ATG does by default if the tag is not already there. If the tag is already there then ATG does a replace by default.

Note that when you do a replace you only need to specify the bare minimum. But what is the bare minimum can be tricky. Here is a case where we made a property hidden. Note that I had to specify the table type as “multi” otherwise ATG assumed it was “auxiliary” even though it’s defined as “multi” in the original XML file.
[xml]<table name="foo" type="multi">
  <property name="bar" hidden="true" />
In another case I wanted to update the id-spaces for orders but I had to first remove before appending because replace did not work in this case. This is how I did it.
[xml]<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<id-space xml-combine="remove" name="order" seed="1" batch-size="10000" prefix="o"/>
<id-space name="order" seed="100" batch-size="1" prefix="m"/>
To see the result of XML combining you can use the Dynamo Administration Server’s Component Browser to go to the component and then click on the property which specifies the XML file(s).

For example to find the result of combining idspaces.xml’s you would go to http://localhost:8080/dyn/admin/nucleus/atg/dynamo/service/IdGenerator/?propertyName=initialIdSpaces.

To find the result of combining productCatalogs.xml’s you would go to http://localhost:8080/dyn/admin/nucleus/atg/commerce/catalog/ProductCatalog/?propertyName=definitionFiles.

To find the result of combining commercepipeline.xml’s you would go to http://localhost:8080/dyn/admin/nucleus/atg/commerce/PipelineManager/?propertyName=definitionFile.

Debug ATG running on JBoss with Eclipse

Configuring Eclipse for Remote Debugging - O'Reilly Media 

With Eclipse debugging an ATG application running on JBoss is fairly straightforward.

  1. Configure JBoss to start up with Java options for debugging.

    On UNIX you do this by uncommenting this line in <JBoss>/bin/run.conf.

    #JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"

    On Windows you do this by uncommenting this line in <JBoss>/bin/run.bat.

    rem set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y %JAVA_OPTS%
  2. Create a remote Java application debug configuration using the port you specified in step 1.  The default port is 8787.

For further reading please see Debugging Nucleus components in JBoss with Eclipse or Remote Debugging with Eclipse.  There is also a very complete tutorial from O’Reilly Media called Configuring Eclipse for Remote Debugging. for valid URL

In one of our ATG servlet’s we were making a normal HTTP call to a page located on our ATG Dynamo server.

url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
reader = new InputStreamReader(connection.getInputStream());

Free Daddy and His Little Shadow Girls at The Skate Park Creative Commons on FlickrHowever when trying to get the input stream we got a FileNotFoundException yet we were able to go to the same URL using a browser. Googling around we found this lovely thread about the same problem.

To summarize the thread, the problem was in our proxy settings which are set on Windows in localconfig/environment.bat and on UNIX in localconfig/ An example of proxy settings on Windows is set PROXY_ARGS=-Dhttp.proxyHost= -Dhttp.proxyPort=8080.

The proxy server did not recognize our machines as valid clients so it rejected our requests. Once we changed the proxyHost argument to point to a valid server then this problem was fixed.

JSP Dynamo Request Retrieval

In JHTML pages, the request object is of class DynamoHttpServletRequest which has many methods that are not part of the HttpServletRequest interface including the very useful resolveName method for looking up components in Nucleus.

In JSP pages on ATG there is no guarantee that the request object is of class DynamoHttpServletRequest. According to the JSP specification the request object always implements the HttpServletRequest interface.

If you need to get the DynamoHttpServletRequest do something like this:

DynamoHttpServletRequest dynRequest  = atg.servlet.ServletUtil.getDynamoRequest(request);

If you need to get a PortalServletRequest do something like this:

PortalServletRequest portalRequest = (PortalServletRequest) request.getAttribute(atg.portal.servlet.Attributes.PORTALSERVLETREQUEST);