Using Ant with WebSphere Studio Application Developer - Part 1 of 3

You can use WebSphere Studio Application Developer to support command-line production build environments in conjunction with common build tools such as Ant. This article explains how to run Ant both inside and outside Application Developer.

Share:

Barry Searle (searle@ca.ibm.com), WebSphere Studio Application Developer Information Developer, IBM Toronto Lab

Photo: Barry SearleBarry Searle is the Migration Team Leader for WebSphere Studio Application Developer. He is a professional engineer who has worked at the IBM Toronto Lab for over ten years on various application development tools. Prior to that he had many years of industry experience developing command and control systems and leading complex communications development projects. You can reach Barry at searle@ca.ibm.com.



Ellen McKay (ecmckay@ca.ibm.com), WebSphere Information Developer, IBM Toronto Lab

Ellen Matheson McKay is an Information Developer for IBM Canada Ltd. She writes online help and publications for WebSphere Studio Application Developer.



21 March 2002

Introduction

So you want to automate your production builds? You can use IBM ® WebSphere® Studio Application Developer (hereafter called Application Developer) to support command-line production build environments in conjunction with common build tools such as Ant.

Part 1 of this article explains how to run Ant both inside and outside Application Developer. It explains:

  • What Ant is
  • Why it is often used
  • How to run Ant inside Application Developer
  • How to run Ant in a Command Prompt window
  • How to start Application Developer "headless"
  • How to download and use the runAnt program, which contains the "headless" Ant support.

Part 2 explains how you can use special Ant tasks for Application Developer production Ant builds of J2EE modules.

Part 3 explains how to create your own Ant tasks to provide specialized build functions.


Download files

The two download files are not part of Application Developer V4 or V5 Early Availability (EA) and are not officially supported. However, Application Developer V5 General Availability (GA) includes these features in the product and they are fully supported. If you have suggestions or encounter problems with the older V4 or V5 EA features, please e-mail Barry Searle . V5 GA is supported via the normal IBM support channel.

Download now .

com.ibm.ant.extras_V4.zip

The Version 4 download file ( com.ibm.ant.extras_V4.zip ) has been tested with Application Developer 4.0.2 and 4.0.3 and works as described, but will not work with future versions of the product (V5 or later). This code includes the setDebugInfo task from the article Non-Debug compilations in WebSphere Studio Application Developer .

com.ibm.ant.extras_V5EA.zip

The Version 5 Early Availability download file ( com.ibm.ant.extras_V5EA.zip ) has been tested with Application Developer 5.0 Early Availability and works as described. It will not work with future versions of the product (V5 GA or later) and it will not work with Version 4.x. The download code changes from Version 4 (described in this article) to Version 5 are:

  • HeadlessAntListener.java has been renamed to HeadlessAntLogger.java and now extends org.apache.tools.ant.DefaultLogger .
  • HeadlessAntRunner.java no longer creates a new HeadlessAntLogger( ) . Instead, it calls addBuildLogger("HeadlessAntLogger") .
  • HeadlessAntRunner.java no longer calls listener.setMessageOutputLevel(...) and super.processCommandLine(args) .

Important: If you download com.ibm.ant.extras_V5EA.zip , you must unzip it into your x:\Ws_installdir\ WSTOOLS\ECLIPSE \plugins directory, where it will create a com.ibm.ant.extras_5.0.0 subdirectory containing a runAnt.bat program and the various programs it requires. (The Version 4 code went into the x:\Ws_installdir\plugins directory.)

Application Developer V5 General Availability

Application Developer V5 GA contains the Headless Ant features and is fully supported. Do not use the V4 or V5 EA downloads. The RunAnt.bat file is now in the directory X:\WSAD5GA_INSTDIR\wstools\eclipse\plugins\com.ibm.etools.j2ee.ant_5.0.1 , and that directory also contains readme.htm . The Eclipse refresh task <eclipse.refreshLocal> has changed to <eclipse.refreshLocal resource="MyProject/MyFolder" depth="infinite"/> .


What is Ant and why should I use it?

Ant is a Java -based build tool that is a subproject of the Jakarta Apache project. It is similar to Make, except that instead of using operating system shell-based commands, it uses Java classes to perform its operations. The build scripts are XML files containing targets and specifying the tasks (operations) required for each. Ant comes with a large number of built-in tasks sufficient to perform many common build operations. You can learn about them in the Ant user manual .

Because Ant is Java-based, it is platform-independent. It is well suited for building Java applications, but can be used for other build tasks as well. One of its important features is that you can use Java to write new Ant tasks to extend production build capabilities. To learn more about Ant, see the section, Ant information and references .


Ant inside Application Developer

Ant support is provided as a built-in feature of Application Developer. You can right-click any XML file and select Run Ant from its pop-up menu. The Execute Ant Script dialog will open, showing the available Ant targets. You can check, in sequence, which ones are to be executed, and the execution sequence will be shown beside each target. You can also select Display execution log to Ant console , which will cause any Ant messages to be displayed in the Ant Console view ( Perspective => Show View => Other => Ant => Ant Console ).

In addition, an Arguments field lets you pass arguments, such as -verbose , to the Ant program. If the Ant script invokes the Ant javac task, then a special -Dbuild.compiler=org.eclipse.pde.internal.core.JDTCompilerAdapter argument must be passed or else you will get a Cannot use classic compiler error. (For Application Developer Version 5, you need to instead specify -Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter .) Similarly, do not use the deprecation="on" option for the javac Ant task or it will crash Application Developer. Either don't specify anything, or else use deprecation="off" .

Create the following echo.xml file inside any of your Application Developer projects.

<?xml version="1.0"?>
   <project name="Echo" default="echo" basedir=".">
      <target name="echo">
         <echo message="HELLO from echo"/>
      </target>
      <target name="dir">
         <echo message="dir of ${basedir}:"/>
         <exec dir="${basedir}" executable="cmd.exe">
            <arg line="/c dir"/>
         </exec>
      </target>
   </project>

Right-click echo.xml and select Run Ant.

Figure 1
Figure 1

The Run Ant dialog shows that you have two targets, echo and dir, and that echo[1] is the default target that will be executed. If you also select dir, it will change to dir[2] and it will be run as the second target. Ensure that Display execution log to Ant console is checked and click Finish . The script will then be run.

Figure 2
Figure 2

The results will be displayed in the Ant Console in Figure 3 below.

Figure 3
Figure 3

Now, right-click echo.xml and select Run Ant to re-run it. This time enter -verbose in the arguments entry field, then click Finish .


Ant TaskView errors inside Application Developer

Try editing your echo.xml file to include the following bad target with a nonexistent task propertyBAD :

<target name="bad">
   <propertyBAD name="MyName" value="MyValue"/>
</target>

Right-click echo.xml and select Run Ant to rerun it. Select bad as your target and click Finish . You will receive the following error message, "Could not create task of type: propertyBAD in the Tasks view" (it will be listed twice). You can partly fix this by changing propertyBAD to property, and then saving echo.xml . The errors in the Task view will remain, because the errors are Ant run-time errors. If you rerun Ant, the error messages will disappear.


Changing the Ant version in Application Developer

Ant 1.3 is shipped with Application Developer 4.0.x. If you need functionality from a different version of Ant, go to the Jakarta Apache site and download the Ant binary distribution that you want. Then, go to the x:\ws_installdir\plugins\org.eclipse.ant.core directory (where x:\Ws_installdir is the directory where you installed Application Developer) and rename ant.jar , antsupport.jar and jakarta-ant-1.3-optional.jar (for example, to *.oldjar ). Drop in your new JARs. If any JAR has a different name, such as jakarta-ant-1.4-optional.jar , edit the plugin.xml file in org.eclipse.ant.core accordingly). Restart Application Developer and your new version of Ant will be active.

Important: If you perform the above steps, you have changed Application Developer and it will no longer be a supported environment. Although everything should still work as before, unexpected results may occur. If you are familiar with developing plug-ins and understand how they are used during startup, you can create a new plug-in directory with a higher version number and a higher version number in its plugin.xml and leave the existing directory as is.


Running Ant outside Application Developer (command line)

The following steps show you how to run your build script outside Application Developer from a Windows® command line.

  1. Set up your PATH to use the internal JRE:
    set PATH= x:\Ws_installdir \plugins\com.ibm.etools.server.jdk\bin;%PATH%
  2. Set up your CLASSPATH with the Ant JAR and the Xerces parser JAR (this command must be all on one line):
    set CLASSPATH=x:\Ws_installdir\plugins\org.eclipse.ant.core\ant.jar; x:\Ws_installdir\plugins\org.apache.xerces\xerces.jar;%CLASSPATH%
  3. Set up your ANT.HOME environment variable:
    set ANT.HOME=x:\Ws_installdir\plugins\org.eclipse.core
  4. Use Java to run Ant and pass in the build script file and desired targets (this command must be all on one line):
    java org.apache.tools.ant.Main -verbose -buildfile x:\Ws_installdir\MYWORKSPACENAME\MYPROJECTNAME\echo.xml echo dir

If you prefer, you can download a Sun Java 2 SDK or IBM Developer Kit for Windows, or you can go to the Jakarta Apache site and download an Ant binary distribution instead of the Application Developer Java and Ant programs.


Running Ant outside Application Developer ("headless" operation)

You now know how to run Ant outside Application Developer. However, an outside build may still need to access Application Developer functions. For example, an outside javac compile requires all dependent classes to be on the CLASSPATH. For projects within Application Developer, this has already been done by setting up the project buildpath (module dependency), so why repeat this and have dual maintenance? Instead, it would be best if the outside build could simply ask an Application Developer project to build itself using the existing project buildpath information. Such a build does not require the GUI to be running. You can have Application Developer launch itself "headless" and run a specified task, typically an Ant build. You need to create a wrapper HeadlessAntRunner that extends AntRunner and attaches a HeadlessAntListener as part of its run method. Try the following HeadlessAntRunner.java .

package com.ibm.ant.extras;
import org.eclipse.ant.core;
import org.apache.tools.ant.*;

public class HeadlessAntRunner extends AntRunner
{
   private HeadlessAntListener listener = null;

   public Object run(Object argArray) throws Exception
   {
      if(listener==null)
      {
         listener = new HeadlessAntListener();
         super.run(argArray, listener);
      }else
      {
         super.run(argArray);
      }
      return null;
   }
   protected void processCommandLine(String[] args) throws BuildException
   {
      if(listener!=null)
      {
         super.processCommandLine(args);
         listener.setOutputMessageLevel(getOutputMessageLevel());
      }
   }
}

As its companion, try the following HeadlessAntListener.java .

Package com.ibm.ant.extras;
import org.eclipse.ant.core;
import org.apache.tools.ant.*;
Public class HeadlessAntListener implements AntRunnerListener
{
   private int level = Project.MSG_INFO;
   public void setOutputMessageLevel(int i)
   { level = i;
   }
   public HeadlessAntListener(int msgLevel)
   { super();
      level = msgLevel;
   }
   public void buildStarted( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("BuildStarted" );
   }
   public void buildFinished( BuildEvent event )
   { if (b.getException() == null)
      { if(event.getPriority() <= level)
         System.out.println("BuildFinished");
      } else
      {
         System.err.println("Build FAILED");
      }
   }
   public void targetStarted( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("TargetStarted "
         +event.getTarget().getName() );
   }
   public void targetFinished( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("TargetFinished "
         +event.getTarget().getName() );
   }
   public void taskStarted( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("TaskStarted "
         +event.getTask().getTaskName() );
   }
   public void taskFinished( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("TaskFinished "
         +event.getTask().getTaskName() );
   }
   public void messageLogged( BuildEvent event )
   { if(event.getPriority() <= level)
      System.out.println("Priority="+event.getPriority()
         +" Message="+ event.getMessage() );
   }
   public void messageLogged(String message,int priority)
   { if(priority <= level)
      System.out.println("Priority="+priority
         +" Message="+ message );
   }
}

If you compile these programs and put them in a JAR called x:\MYPATH\MYHEADLESS.JAR , you can run Application Developer headless and have it run your HeadlessAntRunner with whatever Ant parameters you pass to it. A typical invocation would be (all on one line):

Java -cp startup.jar;x:\MYPATH\MYHEADLESS.JAR
   org.eclipse.core.launcher.Main -application
   com.ibm.ant.extras.HeadlessAntRunner -data
   x:\Ws_installdir\MYWORKSPACE -buildfile
   x:\Ws_installdir\MYWORKSPACE\MYPROJECT\echo.xml echo dir

You can wrap this in a HeadlessAnt.bat batch file containing (all on one line):

Java -cp startup.jar;x:\MYPATH\MYHEADLESS.JAR
   org.eclipse.core.launcher.Main -application
   com.ibm.ant.extras.HeadlessAntRunner %*

Then you run (all on one line):

headlessAnt -data x:\Ws_installdir\MYWORKSPACE -buildfile
   x:\Ws_installdir\MYWORKSPACE\MYPROJECT\echo.xml echo dir

This procedure still requires Java to be on your PATH. Instead, you could change the start of headlessAnt.bat to contain:

x:\Ws_installdir\jre\bin\Java ...

Using the runAnt program

If you download the com.ibm.ant.extras.zip_V4 file below and unzip it in your x:\Ws_installdir\plugins directory, it will create a com.ibm.ant.extras directory containing a runAnt.bat program and the various programs it requires. It contains a com/ibm/ant/extras/RunAnt.class similar to the above HeadlessAntRunner (but has extra features) and it contains com/IBM/ant/extras/HeadlessAntListener.class .

If you run runAnt with no parameters, it will present a simple menu of operations (1. List your Application Developer projects; 2. Run an Ant script). If you specify parameters, it will pass them to Ant inside Application Developer. Try the following command:

runAnt -buildfile x:\Ws_installdir\MYWORKSPACE\MYPROJECT\echo.xml echo dir

Then try the command runAnt , after which you can either type 1, or else type 2 plus the following:

-buildfile x:\Ws_installdir\MYWORKSPACE\MYPROJECT\echo.xml)

The actual RunAnt.java is shown below:

package com.ibm.ant.extras;

import org.eclipse.core.boot.IPlatformRunnable;
import org.eclipse.ant.core.AntRunner;
import com.ibm.ant.extras.HeadlessAntListener;
import org.eclipse.core.resources.ResourcesPlugin;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

public class RunAnt implements IPlatformRunnable
{
   public Object run(Object args)
   {
      System.out.println("Headless RunAnt started");
      String[] antArgs = (String[]) args;
      HeadlessWorkspaceSettings workspaceSettings = null;
      try
      {
         workspaceSettings = new HeadlessWorkspaceSettings();

         if(antArgs.length>0)
            runAntCommands(args);
         else
            runAntMenu();
         }
         catch (Throwable e)
         {;}
         finally
         {
            if( workspaceSettings != null)
            workspaceSettings.restore();
         }
         return null;
      }
      private void runAntCommands(Object args)
      {
         try
         {
            AntRunner a = new AntRunner();
            int msgLevel = a.getOutputMessageLevel();
            a.run(args, new HeadlessAntListener(msgLevel) );
         }
         catch (Throwable e)
         {
            System.out.println("RunAntCommands FAILED Throwable
            exception="+e.getMessage()+"\n" );
         }
      }
      private void runAntMenu() {;} // not shown here - included in
      // attached code
}

Optimizing the "headless" workspace (required for WarExport or EarExport)

In the above RunAnt program a HeadlessWorkspaceSettings object is constructed:

workspaceSettings = new HeadlessWorkspaceSettings();

With this code enabled, the construction of a HeadlessWorkspaceSettings object saves workspace settings and optimizes workspace performance, and a finally clause is used to restore the normal workspace settings. This is not required, but gives a significant performance gain, for the following reasons.

  • The HeadlessWorkspaceSetting object saves the value of the workspace "snapshot" setting (used to enable the default "snapshots" of the workspace state taken at various times) and sets it to false.
  • Then the workspace "autobuild" setting is saved and set to false.
  • The workspace "local history" setting is saved and set to -1 (off).
  • The restore method restores all these settings. If your build.xml script does a lot of complex build operations, these optimizations can save a lot of time.
  • There is another important thing, required by the WarExport and EarExport operations (described in Part 2 of this article). Operations on Web projects invoke the links builder, and this builder tries to read a preference store value, which attempts to use the workbench GUI when it is not running, causing an exception. The current workaround for the RunAnt code is to go through all projects in the workspace and temporarily remove the links builder from the builder list (then later restore it).

How to restore your workspace settings if your build crashes

The optimization described above:

  • Saves workspace settings.
  • Runs the Ant build script.
  • Restores the workspace settings.

Everything should be fine. However, if your build crashes and takes down the JVM, then the finally clause will not be executed and your workspace settings will not be restored. You could use the Preferences window to manually turn your autoBuild and localHistory settings back on, but there is no way for you to re-enable shapshots or re-insert the Links builder into your Web projects.

If you have a crash and need to force the reset of normal workspace settings, you can call a specialized resetWorkspaceSettings Ant task. You could, for example, create a resetWorkspace.xml file as shown below.

<?Xml version="1.0"?>
   <project name="resetWorkspace" default="resetWorkspace" basedir=".">
      <target name="resetWorkspace">
         <resetWorkspace/>
         <echo message="SNAPSHOTS enabled"/>
         <echo message="WEBPROJECT LINKS_BUILDERS enabled"/>
         <echo message="LOCAL_HISTORY enabled"/>
         <echo message="AUTOBUILD **unchanged**, use
            Preferences window to change it if needed"/>
      </target>
   </project>

You must run resetWorkspace.xml from within Application Developer. If you run it as a "headless" RunAnt script, then the RunAnt program saves and then restores the existing (optimized) settings and your resetWorkspace changes do not take effect.

You cannot change files if the ClearCase plug-in is active

There are operations (such as the J2EE EjbDeploy) that create or change files. If the ClearCase plug-in is active, then any resource changes will cause the plug-in to try to load and read its preference store (this is similar to the Links builder problem with WarExport). There is no way to disable this operation. Hence, you may not be able to perform various Ant build tasks if you have this plug-in active.

Go to the plugins\com.rational.clearcase directory, then run enable_vcm.bat to ensure that the plug-in is not active. Later, you can run enable_clearcase.bat (from the same directory) to make the ClearCase plug-in active again. If the ClearCase menu items are not automatically re-enabled in each perspective, then in those perspectives, select Perspective => Customize => Other => ClearCase to re-enable the menu actions.


Refreshing Application Developer projects from SCMs

How can you extract code from a Software Configuration Management (SCM) system as part of a production Ant build? Currently, there are no Ant tasks in Application Developer to do this with its internal SCM interfaces. So you need to use the various SCM tasks as part of the standard Ant distribution, write your own new ones, or use an exec within your Ant script to call a command-line extract operation.

If you store your source code in an SCM system and extract that code to do production builds, and if you are going to use the internal ('headless') Application Developer Ant Tasks, then you need to ensure that your Application Developer workspace is current. To do this, make sure that your Ant build scripts do a refreshLocal on each project before performing other project build tasks:

<target name="someTarget">
   <refreshLocal resource="MyProject" />
   <echo message="do some build stuff here"/>
</target>

refreshLocal is a built-in Application Developer Ant task. Like incremental and javac , it is defined in x:\Ws_installdir\plugins\org.eclipse.ant.core\plugin.xml . As part of your production build process, you can extract production source from your SCM and then invoke a production Ant build. If that build uses internal ("'headless") Application Developer Ant scripts, then ensure that each project has a refreshLocal run on it before it is used.

Warning : If you are extracting updated files from an SCM, and Application Developer has Windows => Preferences => Workbench => AutoBuild enabled, and your project files have changes in them, then you cannot do a refreshLocal from an Ant build script located within that project. The refreshLocal will update the script XML file while it is in use, causing a ResourceException error message and a runAnt build failure. Therefore, you should have a main high-level build script that first performs your SCM extract, then performs a refreshLocal for each of your individual projects, and then finally, invokes sub-builds on each of them.


Production Ant builds without J2EE projects

If you want to use internal Application Developer functions or Ant Tasks as part of your production build process, the above material explains how you can do that and seamlessly include "headless" Ant builds as part of your overall production build. If your application creates J2EE modules (EJB JARs, WARs, EARs, etc.) using Application Developer, then there are special considerations (and special Ant tasks) to support this. See Part 2 of this article, Using Ant and Using WebSphere Studio Application Developer for Production Builds of J2EE Applications.


Overview of Part 2 -- J2EE builds

Application Developer is an excellent tool for developing J2EE modules (EJB JARs, WARs, EARs, etc). During development, some of the deployment descriptor information is stored in ASCII XML files, but these files contain some information in a format convenient for interactive testing and debugging. As part of the Application Developer functions that create (export) stand-alone J2EE modules, this internally optimized deployment descriptor information is merged and changed into standard format. Part 2 includes a set of Application Developer Ant Tasks to perform these build and export functions using the "headless" operations described in Part 1.


Overview of Part 3 -- Creating new Ant tasks

Part 1 and 2 describe a set of production Ant build capabilities. However, you may have additional tasks that you need your build to do. The above section Why use Ant explained that one reason to use Ant is that it is written in Java and you can therefore write new Ant Tasks in Java to extend the build capabilities (as the EJB development team did for the J2EE Ant Tasks). Part 3 explains how to write new Java Ant Tasks to perform the special operations you need.


Summary

This article explained what Ant is, why you might use it, and provided some links to more Ant information. The article then explained how to run Ant inside Application Developer, and how to run it outside Application Developer in a Command Prompt window. The article next explained how to start Application Developer "headless," so that its internal Ant tasks can be used and and project builds can use existing buildpath ("module dependency") information. Finally, the article explained how to download and use the runAnt program, which contains the "headless" Ant support, and gave a brief overview of how to use Ant with SCMs.


Ant information and references

Several sources of Ant information are available from the Jakarta Apache Ant Project:


Downloads

DescriptionNameSize
Code samplecom.ibm.ant.extras_V4.zip  ( HTTP | FTP )0.1 MB
Code samplecom.ibm.ant.extras_V5EA.zip  ( HTTP | FTP )0.1 MB

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=13281
ArticleTitle=Using Ant with WebSphere Studio Application Developer - Part 1 of 3
publish-date=03212002