Recurring Illegal Access Errors in JBoss when running ATG

illegal access

I recently installed ATG 2007.1 with no patches on JBoss 4.0.5.GA.  When I started it up I continually saw these illegal access errors.

16:01:24,296 INFO  [WebappClassLoader] Illegal access: this web application instance has been stopped already.  Could not load org.apache.log4j.Level.
  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1241)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1201)
        at org.apache.commons.logging.impl.Log4jProxy$1.run(Log4jProxy.java:66)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.commons.logging.impl.Log4jProxy.threadContextClassLoader(Log4jProxy.java:88)
        at org.apache.commons.logging.impl.Log4jProxy.(Log4jProxy.java:94)
        at org.apache.commons.logging.impl.Log4JLogger.(Log4JLogger.java:39)
        at sun.reflect.GeneratedConstructorAccessor22.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
        at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529)
        at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:372)
        at atg.nucleus.logging.commons.CommonsLoggingLogListener.logEvent(CommonsLoggingLogListener.java:106)
        at atg.nucleus.GenericService.sendLogEvent(GenericService.java:291)
        at atg.nucleus.GenericService.logInfo(GenericService.java:737)
        at atg.nucleus.GenericService.logInfo(GenericService.java:715)
        at atg.ui.j2edit.model.CachingJ2eeArchiveDirectoryAgent.updateCacheData(CachingJ2eeArchiveDirectoryAgent.java:513)
        at atg.ui.j2edit.model.CachingJ2eeArchiveDirectoryAgent.performScheduledTask(CachingJ2eeArchiveDirectoryAgent.java:573)
        at atg.service.scheduler.ScheduledJob.runJobs(ScheduledJob.java:441)
        at atg.service.scheduler.Scheduler$2handler.run(Scheduler.java:760)

Fortunately this is a common problem and there are many support incidents about it.  Problem Report #144586 says that the problem occurs if:

  1. say “Yes” to deploying Quincy Fund during installation
  2. use startDynamoOnJBoss to run any other application

The work around is to remove Quincy Funds.ear from the JBoss deployment directory.  Or just don’t install Quincy Funds.

If you need to run the Quincy Funds demo then the Error running Quincy Funds demo on JBoss document suggests:

  1. stop the server
  2. delete the ATGDAF.ear from the JBoss installation
  3. start JBoss with the run.bat|sh command; the Quincy Funds demo is automatically started

For further reading please see How to use the startDynamoOnJBOSS script and JBoss configurations to run an application.  You may need to have an active ATG support contract to view these and other ATG support documents referenced in this article.

Questions to Consider When Starting an eCommerce Site

I have done many eCommerce projects and am looking forward to doing more.

The most interesting eCommerce projects are the ones that are starting from scratch.  I was fortunate to be a part of several such projects including NFLShop.com, CasualMale.com and OriginalPenguin.com.  Of these the OriginalPenguin.com project was by far the most interesting because I was simultaneously the director, lead engineer, and QA. 🙂

Whenever I start a project or am consulting for one I ask the following questions to help determine the scope and range of the project.

  1. What technology will be used?  J2EE?  ATG?  .Net?  PHP?  Ruby on Rails?
  2. What platform?  Windows?  Linux?  Solaris?  FreeBSD?
  3. How will it be hosted?  Locally?  Shared host?  Virtual host?  Exclusive host?
  4. What database do you use or plan to use?
  5. How many products, product categories and SKU’s do you have?
  6. How will catalog administration be done?  Should it be part of the web application?  Or will you use a separate third-party application?
  7. How will you manage price lists?
  8. How will you keep track of inventory?
  9. When an order is submitted, how will it be fulfilled?  Who does fulfillment?
  10. How will you handle payments?  Payflow Pro?  Cyber Cash?  CyberSource?  PayPal?
  11. How will you handle taxes?  TAXWARE?
  12. What kind of security do you want?  Will everything be handled securely via SSL?  Do you already have an SSL server certificate for the site?
  13. Will you require that to buy something you have to have an account?  If not will you want to still try to encourage buyers to get an account?  Will you be saving credit card numbers with the account?
  14. Can buyers track their order history, order status, etc.?
  15. What kind of emails do you want sent during the order/fulfillment process?
  16. Will you want to implement promotions and/or coupons?
  17. What kind of catalog navigation do you want?  Do you want a menu like navigation like Amazon.com?
  18. Do you want the buyer to be able to search for items?
  19. Do you want product comparison?

Get JSTL Vars from PageContext

JSTL sets its vars in the pageContext.  For example:

pageContext.setAttribute("foo", bar);


Therefore to get a JSTL variable use the pageContext within a tag or a JSP page.  For example:

// get item from pageContext and put in request
atg.servlet.DynamoHttpServletRequest drequest = atg.servlet.ServletUtil.getDynamoRequest(request);
drequest.setParameter("foo", pageContext.getAttribute("foo"));


Note that getAttribute assumes the variable is in the page scope.  If you want to get a variable from for example the request scope you would do this.

pageContext.getAttribute("foo", javax.servlet.PageContext.REQUEST_SCOPE);


For further reading please see PageContext.

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.

Trim White Space from JSP

Untitled | FlickrSometimes the resultant HTML from JSP files has too much white space.  This is because a lot of JSP logic will result in only a few lines of actual HTML code and the rest is white space.

One efficient way to get rid of white space is to add this configuration to your web.xml on Tomcat/JBoss as described in this article, Trim Spaces in your JSP’s HTML.

/jboss/jboss-eap-4.2/jboss-as/server/atg/deploy/jboss-web.deployer/conf/web.xml
OR
/jboss/jboss-eap-5.1/jboss-as/server/atg/deployers/jbossweb.deployer/web.xml

<servlet>
    <servlet-name>jsp</servlet-name>
    ...

    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>

    ...
</servlet>


However this sometimes has undesired side-effects. For example this DSP:

<div class="foo">
  <dspel:valueof param="displayName" />
</div>


causes this undesired result:

<div class="foo"/>
  Frank Kim


The work around is to do this.

<dspel:getvalueof  var="displayName" param="displayName" />
<div  class="foo"><c:out  value="${displayName}"/></div>

Update 06-09-2010: The above problem might have been happening because we were running with a version of ATG that is for Servlet 2.3. When we run with a version of JBoss that runs with Servlet 2.4, e.g.  ATG 9.1 with JBoss EAP 4.2, we no longer see this problem.

There is another tip on removing white space in this JSP FAQ: Why I am getting extra whitespace in the output of my JSP?  In our code we had one file which included a bunch of tag libraries.  It originally looked like this.

<%/** Taglibs.jsp: include to pull in all taglibs */%>

<%@ taglib uri="/dspELTaglib" prefix="dspel" %>
<%@ taglib uri="/jstlCoreTaglib" prefix="c" %>
<%@ taglib uri="/struts-bean" prefix="bean" %>
<%@ taglib uri="/struts-tiles" prefix="tiles" %


When we changed it to this we saved about 5% in terms of page size in bytes.

<%@ taglib uri="/dspELTaglib" prefix="dspel"
%><%@ taglib uri="/jstlCoreTaglib" prefix="c"
%><%@ taglib uri="/struts-bean" prefix="bean"
%><%@ taglib uri="/struts-tiles" prefix="tiles" %>


You can use this tip with a DSP page and maintain indentation.

<dspel:page    ><dspel:droplet name="/betweengo/droplet/Foo"      ><dspel:oparam name="output"        >Name: <dspel:valueof param="name"      /></dspel:oparam    ></dspel:droplet
></dspel:page>

Sets cannot be used as property types

I create a JavaBean with a Set property because I wanted to enforce that there were only unique values in that Set.  However when I tried to use this JavaBean with a properties file, Nucleus complained it could not resolve the elements of the Set property.  When I changed the property to be a List or a String [] Nucleus had no problem.

Here is the properties file.

$class=com.betweengo.droplet.VerifyImages
$scope=request

# supported image dimensions
supportedImageDimensions=75x90,88x31,120x90

ATG Support pointed me to the Property Types subsection of the Using Nucleus
section of the ATG Programming Guide.  Specifically only these simple types are supported.  I am not sure why Set was excluded.

boolean
byte
char
short
int
long
float
double
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
java.lang.String
java.util.List
java.util.Map
java.util.Locale

Repository creating tables automatically

Recently we noticed while running some ATG unit tests that tables were being created by the ATG repository if they had not already been created by our SQL scripts.  This was a functionality that I was unaware of but apparently it is not unique, Hibernate does this too.  I could not find any documentation about this nor could I determine how to turn it off.

The ATG repository creates these tables using the repository definition and the defaults for column width and data type.  It does not seem to warn that it is creating these tables.

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