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
runAntprogram, 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.
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.
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
.
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.javahas been renamed toHeadlessAntLogger.javaand now extendsorg.apache.tools.ant.DefaultLogger. -
HeadlessAntRunner.javano longer creates a newHeadlessAntLogger( ). Instead, it callsaddBuildLogger("HeadlessAntLogger"). -
HeadlessAntRunner.javano longer callslistener.setMessageOutputLevel(...)andsuper.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
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
The results will be displayed in the Ant Console in Figure 3 below.
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.
- Set up your PATH to use the internal JRE:
set PATH= x:\Ws_installdir \plugins\com.ibm.etools.server.jdk\bin;%PATH%
- 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%
- Set up your ANT.HOME environment variable:
set ANT.HOME=x:\Ws_installdir\plugins\org.eclipse.core
- 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 ... |
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
HeadlessWorkspaceSettingobject 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.xmlscript 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
RunAntcode 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\plugi
ns\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.
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:
- Ant user manual
- Ant user mail list
- Ant user mail list archives
- WebSphere Version 4.0 Application Development Handbook (Chapter 9) explains how to use Ant to build a WebSphere application.
- Automate your build process using Java and Ant -- JavaWorld article
- Open Source Java: Ant -- onjava.com article
| Name | Size | Download method |
|---|---|---|
| com.ibm.ant.extras_V4.zip | 0.1 MB | FTP |
| com.ibm.ant.extras_V5EA.zip | 0.1 MB | FTP |
Information about download methods

Barry 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.



