JRebel How-to: Zero Restarts with Oracle ATG Web Commerce

JRebel Tutorial: Using JRebel with Oracle ATG Web Commerce

This how-to shows a JRebel/ATG integration that re-initializes the values of an ATG service when the backing Java class is changed, thus preventing the need to restart the application server (redeploy). The current version of JRebel has been tested with ATG10.1 and ATG 2007.4.

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.
     

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>

 

atg_workspace_jsp1

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;
 }
}


atg_workspace_java1-1024x336


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, is 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