Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.

JRebel rescues Oracle ATG Web Commerce users from Redeploy Madness

Introduction and a little history

You may remember that back in 1991, two MIT graduates set up an IT company called Art Technology Group (ATG), which grew into a successful provider of eCommerce and business applications before being acquired by Oracle for $1 billion in early 2011. The ATG Web Commerce framework is now under the Oracle umbrella, and it mostly used by large Enterprise providers to develop advanced eCommerce applications.

Because JRebel is an all-Java plugin (meaning that it will work, give some small integration effort, with anything on the JVM), some customers have tried to integrate JRebel with ATG out-of-the-box without knowing for sure what would happen. Although we already support 47 different web and server side frameworks, not all the changes a user makes to their code base will be supported without some tender love and care from our JRebel APIs team.

Out of the box, JRebel will reload code changes to class structures in ATG, but when making configuration changes, JRebel didn’t (until now!) support any ATG specific configuration re-initialization when the underlying classes were changed.

After some time, several larger clients let us know that is would be really quite cool if a service in ATG would be reloaded when the service’s Java class is changed. The services in ATG are something like Spring beans, configured by property files, consisting of multiple property files that define a service with a Java class. They can reference each other and initialize classes with properties, similarly to Spring beans.

And that’s how additional support for the thousands of Java technologies is born here at ZeroTurnaround – just ask us enough and we’ll jump on it.

So we went on and wrote an ATG integration that re-initializes the values of an ATG service when the backing Java class is changed, thus preventing Redeploy Madness among ATG users. The current version of JRebel has been tested with ATG10.1 and ATG 2007.4.

ATG you beast, how can I love you?

To integrate ATG with JRebel, we needed to get a simple, standalone ATG application working, but we didn’t want to install a big database server. For our needs, we only wanted it to simply run in order to understand the entire application.

But when we browsed the mighty internets, we didn’t find a good example. Yes, ATG has some examples with it, but they are big, really BIG. In addition to ATG, you must install a database server just to get a simple “Hello World!” application in the works.

Finally, we managed to strip an ATG application down to only a handful of files, which we could easily understand. Since we think we are getting paid to do this stuff (right, boss?), we figured that other users would be interested in grabbing an easily-understandable, stripped down version of a sample ATG application without having to go through all the documentation. So here it is…Introducing “Hello Rebel”, a simple ATG application…

Goals

These are the end goals of this how to:

  • Building a simple, standalone step-by-step ATG application (“Hello Rebel”).
  • Avoiding database installation – Use of an embedded database.
  • Using JRebel for reloading lots of changes on the fly, without restarting.
  • Finishing with a deployable ZIP that contains the demo application.

Note: We made a separate JRebel tutorial page for the actual how-to in case you want to see only the gritty tech of it all outside of the blog context, but the content is identical to what you see below, and here you can see comments as well.

Getting started

First you need to download the ATG framework from the oracle.com. You will need to create an user for the Oracle site and you must check the “Yes, I’d like to become a member of the Oracle Technology Network (OTN)” flag on your Oracle account page. Then you can download the ATG by:

Download » Applications » “E-Business Suite, PeopleSoft, JD Edwards, Siebel CRM” » ATG Web Commerce » Oracle ATG Web Commerce (10.1.1)

Here are a few more things that you’ll need for this tutorial before we get started:

  • Embedded database – HSQLDB (2.2.9)
  • For really fast development cycle – JRebel
  • You will also need an application server to run your application. We used WebLogic 10.3.5.

Installing the software

Because we want to concentrate more on writing the “Hello Rebel!” sample application, we will quickly fly over the preparations.

First you must install your application server. We used WebLogic 10.3.5. with the default values and “Typical” configuration and created a default domain with AdminServer. We had already installed JRebel, so we add the JVM arguments according to the manual.

After that you should install ATG. We used the default location and installed all the products; when it asked for the server we pointed it to the WLS we just installed.

Writing “Hello Rebel!”

Now to the fun part, writing the actual application! We start off by creating an empty directory atg-hello-demo under ATG home.

Next we create a simple application in that new folder.

  • Create a folder: atg-hello-demo\demo
  • Create a jsp: atg-hello-demo\demo\index.jsp
  • <%@ taglib uri="/dspTaglib" prefix="dsp" %>
    <dsp:page>
    <html>
    <head><title>Hello</title></head>
    <body>
    Hello
    <dsp:droplet name="/test/TestService">
    </dsp:droplet>
    </body>
    </html>
    </dsp:page>
    

    will be the ATG Nucleus service we are using.

  • Create atg-hello-demo\demo\META-INF
  • Create atg-hello-demo\demo\META-INF\MANIFEST.MF
  • Manifest-Version: 1.0
    ATG-Module-Uri: demo.war
    ATG-Context-Root: demo
    
  • Create atg-hello-demo\demo\WEB-INF\web.xml
  • <?xml version="1.0" ?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
     <display-name>Demo Web Application</display-name>
     <context-param>
        <param-name>atg.session.parentContextName</param-name>
        <param-value>/dyn</param-value>
     </context-param>
     <context-param>
        <param-name>atg.dafear.bootstrapContextName</param-name>
        <param-value>/dyn</param-value>
     </context-param>
     <servlet>
        <servlet-name>NucleusServlet</servlet-name>
        <servlet-class>atg.nucleus.servlet.NucleusServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
        <servlet-name>NucleusServlet</servlet-name>
        <url-pattern>/nucleus/*</url-pattern>
     </servlet-mapping>
     <filter>
        <filter-name>PageFilter</filter-name>
        <filter-class>atg.filter.dspjsp.PageFilter</filter-class>
     </filter>
     <filter-mapping>
        <filter-name>PageFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
     </filter-mapping>
     <jsp-config>
        <jsp-property-group>
         <url-pattern>*.jsp</url-pattern>
         <page-encoding>UTF-8</page-encoding>
         <scripting-invalid>true</scripting-invalid>
        </jsp-property-group>
        <taglib>
         <taglib-uri>/dspTaglib</taglib-uri>
         <taglib-location>/WEB-INF/taglibs/dspjspTaglib1_0.tld</taglib-location>
        </taglib>
     </jsp-config>
     <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
     </welcome-file-list>
    </web-app>
    

    The NucleusServlet in the web.xml is important because it starts ATG.

  • Now we need to add taglibs for the JSP tags. The simplest way would be to copy them from another project: Copy the lib and taglibs directories from DCSSampleCatalog\j2ee-apps\sampleCatalog\web-app\WEB-INF to atg-hello-demo\demo\WEB-INF
  • Now we have the application ready and can start with the ATG configuration.

    Creating an ATG service for “World”

    Now we must make the “TestService” that we used in the JSP.

  • Create a folder: atg-hello-demo\services
  • Create a folder: atg-hello-demo\services\demo
  • Create a Java file: atg-hello-demo\services\demo\TestService.java
  • package demo;
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import atg.servlet.*;
    public class TestService extends DynamoServlet {
     int age;
     public TestService () {
        System.out.println ("Constructing TestService");
     }
     public void service (DynamoHttpServletRequest request, DynamoHttpServletResponse response) throws ServletException, IOException {
        System.out.println ("servicing TestService "+age);
        ServletOutputStream out = response.getOutputStream ();
        out.println ("World! My age is "+age);
     }
     public int getAge () { return age; }
     public void setAge (int age) {
        System.out.println ("setting age of TestService to " + age);
        this.age = age;
     }
    }
    

    Click on the image to see the larger version so you don’t have to squint your eyes:

  • Create a rebel.xml: atg-hello-demo\services\rebel.xml
  • <?xml version="1.0" encoding="UTF-8"?>
    <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">
       <classpath>
           <dir name="..path..to../atg-hello-demo/services"> </dir>
       </classpath>
    </application>
    

    This “services” folder will be added to the classpath of the application.

    Now we create the configuration for the service

  • Create a folder: atg-hello-demo\config
  • Create a folder: atg-hello-demo\config\test
  • Create a properties file: atg-hello-demo\config\test\TestService.properties
  • $class=demo.TestService
    age=5
    

    Now the configuration of the service is complete.

    Configuring the database

    ATG supports data sources configured by your application server. Because we want to make a simple example and don’t want the user to install a database server we decided to use HSQLDB.

  • Create a folder: atg-hello-demo\lib
  • From the hsqldb site download: commons-dbcp.jar and hsqldb.jar and add them to the lib folder.
  • Create a script file for the initial data: atg-hello-demo\services\database.script
  • The actual project is also available at our github project. It includes the default DB tables that the ATG core needs to run. We created this script based on the MySQL script provided with ATG, so with a newer/older ATG version some things might be different.

  • Configure ATG to use the new database. Create the needed folders to make the following file: atg-hello-demo\config\atg\dynamo\service\jdbc\DirectJTDataSource.properties
  • $class=org.apache.commons.dbcp.BasicDataSource
    driverClassName=org.hsqldb.jdbcDriver
    url=jdbc:hsqldb:res:database
    

    Finishing the application

    Now we have only a few things left to do before the demo is ready.

  • Create a folder: atg-hello-demo\META-INF
  • Create a META-INF directory under it and add MANIFEST.MF. This describes your new ATG module. An example of the manifest file would be:
  • Manifest-Version: 1.0
    ATG-Builder: andres.luuk@zeroturnaround.com
    ATG-Product: atg-hello-demo
    ATG-Version: 10.1
    ATG-Config-Path: config/
    ATG-Class-Path: lib/commons-dbcp.jar lib/hsqldb.jar services
    ATG-Web-Module: demo
    

    Explanations of the parameters:

  • ATG-Product: atg-hello-demo — Name of this module
  • ATG-Config-Path: config/ — ATG configuration/properties files for this module
  • ATG-Class-Path: lib/commons-dbcp.jar lib/hsqldb.jar services — Additional jars and Java classes used by all the applications of this module.
  • ATG-Web-Module: demo — The demo application for this module
  • Testing the application

    Now that your application is ready, you can package it to deploy on the server you’ve already configured. Go to ATG home\bin of the ATG installation and run:

    runAssembler testDemoEar.ear -m atg-hello-demo

    Now you can deploy the testDemoEar.ear on your local machine and if you go to the applications test URL, in our case with weblogic: http://localhost:7001/demo/index.jsp

    You should see:

    Hello World! My age is 5

    Testing the reloading, from “World” to “Rebel”

    Now to test that we need to make some changes:

    go to atg-hello-demo\config\test\TestService.properties and change

    age=5

    ->

    age=25

    go to atg-hello-demo\services\demo\TestService.java and change

    out.println ("World! My age is "+age)

    ->

    out.println ("Rebel! My age is "+age)

    Set the environment for compiling: home\bin>dynamoEnv.bat

    And compile the TestService: atg-hello-demo\services>javac demo\TestService.java

    Refresh your browser and you should see:

    Hello Rebel! My age is 25

    Just a reminder, this demo application is available at Github project.

    Final Words

    ATG might have started in the early days of modern IT, but it doesn’t mean you still need to reside in the old days of Java with slow restarts for every change you make to a configuration file or class structure. For you ATG users out there that are tired of long restarts every time you make a change, then try JRebel out.

    We depend on your feedback for this sort of thing too, please know that we’ll be grateful if you let us know how useful it is, what, if anything, does not work, and if there are any other support for ATG that you’d like to see. You can leave comments below, or write to me directly at andres.luuk@zeroturnaround.com