Build Artifacts Publishing and Automated Build Output Management Using the Plain Java Client Libraries

The Jazz Build Engine is unfortunately very limited with respect to publish build results. Can this be done better? Is it possible to automatically move the data of special builds into artifact repositories? I have published some articles in the library  long ago. Since the situation hasn’t really changed, I wanted to publish them here for completeness and to make them easier to find.

The Jazz development uses a similar approach (albeit not that basic) to manage their builds.

See a comparison of binary repository managers.

Publishing Build Output Files

It is possible to upload logs and result files to the build result of a Jazz Build Engine (JBE) build run.

However, uploading big files just makes the repository bigger. Even worse, clicking on any uploaded logs and other uploaded files on a build result leads to downloading the file to the local disk, where the file can hopefully be opened with a local editor.

This does not scale well and ideally it would be nice if all that is in the build result is a link to the build and the supporting result files which one could see in a browser. It would also be interesting to be able to see a web page for each build that shows statistics and result details.

How can this be done easily?

The article Build Artifacts Publishing Using HTTP Servers in Rational Team Concert shows a simple scenario how to do this and have a direct browser-based access to all of the build result files.

As a summary the basic approach used in the article Build Artifacts Publishing Using HTTP Servers in Rational Team Concert is to have the build files, including the built files and the build result information stored somewhere (on a disk) and only publish the URL to that location back to the build result for navigation. The URL is just an index file in the simplest example, it could be far more complex and, for example, contain statistics, test results and test coverage information.

Management of Build Output and Backup or Using Artifact Repositories

Publishing basically means keeping the loaded build repository workspace and the generated files somewhere, and publish them with a HTTP server. No matter how cheap disk space might be, at some point in time you want to get rid of outdated build data that is not referenced any more. You also want to make sure to back up and keep the relevant build data needed to be preserved such as released versions.

The article Automated Build Output Management Using the Plain Java Client Libraries explains how to do this by creating a small RTC Plain Java Client Library application that purges build data and results, allows to back up the relevant builds and to store them in an artifact repository. The example code has a placeholder for this step using IBM Rational Asset Manager. By copying files or using an API this could target any system. Provided the system publishes the data back into the web, the example shows code to add the link to the location in the artifact repository to the build result for later reference.

License and Download

The post contains published code, so our lawyers reminded me to state that the code in this post is derived from examples from as well as the RTC SDK. The usage of code from that example source code is governed by this license. Therefore this code is governed by this license. I found a section relevant to source code at the and of the license. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!

You can download the project source code from here. Please note, there might be restrictions to access Dropbox and therefore the code in your company or download location.

Just Starting With Extending RTC?

If you just get started with extending Rational Team Concert, or create API based automation, start with the post Learning To Fly: Getting Started with the RTC Java API’s and follow the linked resources.

You should be able to use the following code in this environment and get your own automation or extension working.

The Build Output Manager

I will not show the whole code here, only some special parts that are interesting. How the code works and more reasoning can be found in the article Automated Build Output Management Using the Plain Java Client Libraries. To run this tool assumes a setup as described in the article Build Artifacts Publishing Using HTTP Servers in Rational Team Concert and the one above.

The code provided is for a more complete version of the Build Output Manager published before, it can actually delete folders and it can be run in a simulation mode. It also creates console output with more information.

The project looks as follows:

Java Project

The folder src contains the single class that makes up this tool.

The folder build contains a jardesc file that can be used to create the Jar file that allows to run it.

The folder BuildPublishing contains an example ant  build script for result publishing and an example for an Apache configuration.

The root folder contains a file RunManager.bat and that runs the jar file and the class within assuming the jar file is in the same folder. The files define the location for the JAVA_HOME and the location of the Plain Java Client Libraries files. The structure is set up to allow to copy the Jar file and the shell scripts into a sub folder of the installs folder of a Extensions workshop environment and run it. As an example name the folder BuildResultManager. Change the paths if needed.

Folder with JAR file and Scripts

The root folder also contains the file ReadMe – HowToRelease.txt which explains how to build and release the tool. follow the description to release your version.

What the Build Output Manager Does

The general idea is described in the article Automated Build Output Management Using the Plain Java Client Libraries. Here a short summary.

Given a build result root folder that contains sub folders for each build, the Build Output Manager literates the sub folders. For each sub folder it checks if there is a file available that contains the information needed to identify the build result and the RTC repository.

If there is a file, the Build Output Manager uses the information inside and contacts the RTC server to check if the build result is still available. If it can find the build result, it checks its details.

It checks if the build result has been marked as a deliverable (also called release) since it last checked. If it is marked as a deliverable, the build is important and needs to be preserved, in order to satisfy the links back from the build result. At this point it would also be interesting to create a backup of the build data and/or move the build data into an artifact repository.

The code here has a stub method addToBackUp() that pretends to store the data in the IBM Rational Asset Manager. This could be enhanced to work for any other artifact repository or backup system. The existing code also shows how to publish the link information to the artifact in the repository back to the build result. For builds identified as deliverable, the code creates a new file in the build result folder that marks this folder as deliverable. This file is used in subsequent runs to skip any checks and thus preserves the folder from deletion.

If the build result is no longer available the Build Output Manager assumes that the build result was purged and the build result folder can be deleted.

If there is no file, the Build Output Manager can not really determine anything in the repository. However, it can act on aging and other information and has some code built-in the method handleNotQualifyingFolders() to help dealing with this situation and some flags to control its behavior.

By default all non qualifying folders (lacking the file) are checked for aging. All over a certain age are checked if they should be deleted based on special settings in the Build Output Manager. If the Build Output Manager is set to delete these folders, the deletion is performed.

All non qualifying folders that are past the aging threshold and are not deleted are collected in a list as deletion candidates. After processing all folders, the Build Output Manager publishes a list of notifications for all the remaining candidates for deletion by aging that are left over. This notification provides information in a human readable format that could be used by an administrator to check what is going on.

The information below is the result of a run with the default parameters.

Example output:

Process Build Result ID: _q47SAH2OEeWt7sIN-jhQsg	 in folder: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20151028-1712
	Processing Build Result[UUID _q47SAH2OEeWt7sIN-jhQsg]	 May be deleted	 Personal build	Status:COMPLETED
Process Build Result ID: _wz8NAX2QEeWt7sIN-jhQsg	 in folder: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20151028-1727
	Build result no longer in repository: _wz8NAX2QEeWt7sIN-jhQsg
	DELETING: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20151028-1727
Process Build Result ID: _ZsVi0X2REeWt7sIN-jhQsg	 in folder: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20151028-1731
	Processing Build Result[UUID _ZsVi0X2REeWt7sIN-jhQsg]	 May be deleted	 Personal build	Status:COMPLETED
Process Build Result ID: _QEDkgX2SEeWt7sIN-jhQsg	 in folder: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20151028-1738
	Processing Build Result[UUID _QEDkgX2SEeWt7sIN-jhQsg]	 May be deleted	 Personal build	Status:COMPLETED

Deletion Candidates:
Folder should be deleted: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\C20150429-1043	 age: 183	days. Jazz SCM metadata detected!
Folder should be deleted: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20150407-1128	 age: 205	days. Jazz SCM metadata detected!
Folder should be deleted: C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild\I20150407-1238	 age: 204	days. Jazz SCM metadata detected!

For the folders that contain a file the Build Output Manager checked if the build result in RTC has been deleted (i.e. while purging results).  For the build folder label I20151028-1727 build result ID _wz8NAX2QEeWt7sIN-jhQsg was identified but the build result could no longer be found in the repository and the folder was deleted (simulation only with default parameters).

The Build Output Manager detected the folder C20150429-1043 that is 183 days old but has no file. It also detected that the folder contains jazz SCM metadata. This is an indicator that it was created during a repository workspace load operation and is likely to be a build output folder (as opposed to a folder containing cute cat videos).

These folders could have been created by builds that run on a build definition or with build scripts, that don’t create the file themselves. It might be a good idea to somehow fix this situation. There is a special flags available to deal with situations like this and automatically delete these folders based on age.

If there is no indication of Jazz SCM metadata, this would also be announced. These folders are likely to be folders that have been manually created for other purposes. There is a special flags available to deal with situations like this and automatically delete these folders based on age. However this is an extreme measure and I would suggest to check first if there is not something else going on and make sure the folders in the build output root folder are only created during builds.

RTC Build Result Pruning

RTC has a basic capability to prune build results. The pruner removes unwanted build results from the repository, which ideally drives which build output folders should be deleted. See the article Automated Build Output Management Using the Plain Java Client Libraries for sone more information on that. This capability is very basic. If it seems not be satisfying see Robins blog post about creating a Custom build result pruner that implements a more anhanced strategy. Since this is also based on the Plain Java Client libraies, it would be possible to integrate it with the Build Output Manager discussed in this post.

How to Run the Build Output Manager Tool

The Build Output Manager has the following required parameter

 BuildOutputManager [repositoryURI] [userId] [password] [BuildResultRoot]

The Build Output Manager needs the repository that contains the build results. Currently it will not work with build results that are detected to be in a different repository.

The userID and the password have to be provided and the user has to have the permissions to read and modify the build results.

The Build Output Manager must be run in the context of a user that has permission to read and delete the build output folders.

Here an example for the parameters:

"" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild"

If only these parameters are provided, the tool runs in a default mode. Currently the default mode is internally set to simulation.

The following additional parameters can be added at the end of the parameter list.

  • simulation – the Build Output Manager only simulates operations and does not delete any folders and the result is reported (current default mode)
  • deleteUnreferencedBuildfolders – the Build Output Manager tries to identify build folders that contain the file; it performs the operations to handle deliverables and deletes the build result folders if they are not a deliverable and a related build result can no longer be found
  • deleteIfSCM – the Build Output Manager performs the operations specified for the mode deleteUnreferencedBuildfolders; in addition all folders that don’t contain a file but are detected to contain Jazz SCM metadata and exceed the aging limit are deleted
  • forceDelete – the Build Output Manager performs the operations specified for the mode deleteUnreferencedBuildfolders; in addition all folders that don’t contain a and exceed the aging limit are deleted

Example parameters:

"" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild" simulation
"" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild" deleteUnreferencedBuildfolders
"" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild" deleteIfSCM 
"" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild" forceDelete

An example when calling the RunManager script.

RunManager "" build build "C:\CLM2014\5.0.2\jazz\buildsystem\buildengine\eclipse\JKEBuild" deleteUnreferencedBuildfolders

You can run the Build Output Manager from chron jobs if it is deployed on the machine running the build engine or containing the build output folders. Another approach would be to use the JBE and have a specific build definition for each engine to run the tool. In any case the tool needs to be run in a user context that has the required permissions to access and delete the files and folders.

Interesting Parts of the Code

Lets look at some of the interesting parts of the code with respect to the RTC Java API. The details can be found in the article Automated Build Output Management Using the Plain Java Client Libraries.

The code below uses the build result ID from the file to

  1. Create a build result handle
  2. Query the RTC item manager for the resolved build result using the permission aware API
  3. If there is anything the user is denied to retrieve, the code assumes the result is there, but not accessible so a warning is issued and the folder is skipped
  4. If the result is not found the assumption is, that it has been purged and the build output folder is deleted
  5. If the result can be found the folder is preserved and the result is used to check if the build has been changed to a deliverable
private void manageFolders() throws TeamRepositoryException {

		System.out.println("Process Build Result ID: " + buildResultID
				+ "\t in folder: "
				+ aBuildOutputCandidate.getAbsolutePath());
		IBuildResultHandle resultHandle = (IBuildResultHandle) IBuildResult.ITEM_TYPE
				.createItemHandle(UUID.valueOf(buildResultID), null);
		ArrayList handleList = new ArrayList();
		IFetchResult fetchResult = aTeamRepository.itemManager()
						IItemManager.REFRESH, null);
		if (fetchResult.hasPermissionDeniedItems()) {
			// can't access but there is a build result
			System.out.println("\t " + buildResultID
					+ " access demied, check permissions!");
		if (fetchResult.hasNotFoundItems()) {
			System.out.println("\tBuild result no longer in repository: "
					+ buildResultID);
		List retrieved = fetchResult.getRetrievedItems();
		for (Iterator iterator = retrieved.iterator(); iterator.hasNext();) {
			Object result = (Object);
			if (result instanceof IBuildResult) {
				IBuildResult buildResult = (IBuildResult) result;
				processBuildResult(aBuildOutputCandidate, buildResult);


The code to process the build result is shown below.

 * Process the build result for additional information that might be useful.
 * For instance check if the Build Result is associated with a deliverable.
 * @param aBuildOutputCandidate
 * @param buildResult
 * @throws TeamRepositoryException
private void processBuildResult(File aBuildOutputCandidate,
		IBuildResult buildResult) throws TeamRepositoryException {
	System.out.println("\tProcessing Build Result"
			+ buildResult.getItemId()
			+ "\t "
			+ (buildResult.isDeleteAllowed() ? "May be deleted"
					: "Deletion not allowed")
			+ "\t "
			+ (buildResult.isPersonalBuild() ? "Personal Build"
					: "Public Build") + "\tStatus:"
			+ buildResult.getState().toString());
	if (!buildResult.getState().equals(BuildState.COMPLETED)) {
		return; // Only handle completed builds
	IWorkItemCommon workItemCommon = (IWorkItemCommon) aTeamRepository
	List deliverables = workItemCommon
					IDeliverable.FULL_PROFILE, null);
	if (null != deliverables && !deliverables.isEmpty()) {
		System.out.println("\tDETECTED DELIVERABLE: "
				+ aBuildOutputCandidate.getAbsolutePath()
				+ "\t Mark folder and schedule back up of folder!");
		addToBackUp(aBuildOutputCandidate, buildResult);

The code below deals with a build that is identified as deliverable and needs to be preserved.

 * Stub for calling a backup operation for a release folder.
 * @param buildResult
 * @throws TeamRepositoryException
private void addToBackUp(File aBuildOutputCandidate,
		IBuildResult buildResult) throws TeamRepositoryException {
	if (isMarkedAsDeliverable(aBuildOutputCandidate)) {
	String theURL = publishToIRAM(aBuildOutputCandidate);
	IBuildResultContribution link = BuildItemFactory
	// Optional set a category
	// link.setComponentName("Build Output Backup for Audits");
	link.setLabel("Download Artifact from IBM Rational Asset Manager");
			IBuildResultContribution.PROPERTY_NAME_URL, theURL);
	ITeamBuildClient buildClient = (ITeamBuildClient) aTeamRepository
			(IBuildResultHandle) buildResult.getItemHandle(), link, null);

private String publishToIRAM(File aBuildOutputCandidate) {
	return "";

The interesting part of this code is the part that adds a link to the artifact repository on the build result, which allows users to navigate there.

The publishing to an artifact repository in the method publishToIRAM() is not implemented, but it would obviously be possible to add the code required for the artifact repository of your choice. It should return an URL to the published artifact.

Interesting Related Posts


This example was created a long time ago, but I think it is still of interest. Keep in mind this is by no means production code. You might want to do more testing and enhance it to your needs. As always I hope this helps someone out there to get their job done more efficient.

Publish and Host XML Data Using Tomcat – The Easy Way

Why I missed this easy solution beats me, however, as my team mate Freddy points out in his (e-mail) answer to my comment on his blog about HTTP Filtered Value Sets it is even easier to publish XML data – or any other data – on Tomcat than by creating a web application as described in my last post.

* Update *: See Publishing XML and Other Data With the WAS Liberty Profile for how to do this with the WAS Liberty Profile.


Basically what you have to do is to publish it in the folder $CATALINA_HOME/webapps/ROOT/. In the context of a Jazz Team Server that is the folder /server/tomcat/webapps/ROOT/. If you have a file test.xml you want to publish on your Tomcat server you can copy it directly into that folder or into a sub folder structure.


To publish the given file makers.xml from the last post as  https://localhost:9443/PEWEnactmentData/makers.xml, assuming a standard Jazz Tomcat deployment.

  • Create a folder PEWEnactmentData in the folder <InstallDir>/server/tomcat/webapps/ROOT/
  • Copy the file makers.xml into the newly created folder

The File is now accessible as https://localhost:9443/PEWEnactmentData/makers.xml as intended. Replace localhost with your fully qualified hostname in your deployment.

Note: Please make sure that your Folder Name does not conflict with the context root of any web application you have deployed on Tomcat.


Given this approach it is as easy to use Tomcat to maintain your data for HTTP Filtered value providers as using Apache.

This is also a good example how hard it can be to find information in the Internet. I tried to search for publishing XML on Tomcat with what I learned from Freddy, and I did not find an answer to the question really. All the discussions are around deploying applications.

Publish XML Data Using Tomcat – Hotfix for The Process Enactment Workshop

Can you publish XML files for the HTTP Filtered Value Set on Tomcat? This was a question I asked myself when working on Lab 4 of the Process Enactment Workshop. My first answer, and also response to this forum question was: No.

Dead Wrong. It is of course possible to do so. I just did not know how to do that. This post shows how you can indeed do this.

You can download a WAR File that contains the data for the Process Enactment Workshop here.

* Update *: See this post for an even easier way to publish your data on Tomcat.

* Update *: See Publishing XML and Other Data With the WAS Liberty Profile for how to do this with the WAS Liberty Profile.


I needed to provide an example for the HTTP Filtered Value Set in the workshop. Since this Value Set requires the XML published by a HTTP server, I basically saw two options: download and install Apache as described here, and place the XML document into the htdocs sub-directory for publishing. I could also use an existing example like I did not want to add the effort and time to install Apache, even if it is quite straight forward. I thought about publishing on Tomcat but digging the internet did not show an easy way to do it. So I chose to use Some days ago the inevitable happened. That web site does not provide the information I need any longer.

Available Options

Now I was again down to the two choices:

  1. Install Apache
  2. Find a solution with Tomcat.

I still did not like the Apache solution, at least for the workshop, as it adds a lot of waiting time due to the install, although I will describe it shortly below. So I decided to take a deeper look at Tomcat. I found a relatively easy solution to make it possible with Tomcat too.

Apache Solution

Download and install Apache, e.g. into the folder C:/Apache and provide a reasonable host name during the install. After the install is done, by default the sub-directory C:/Apache/htdocs is used as root for publishing. If you run C:/Apache/bin/httpd and place a document, for example makers.xml into the folder it is accessible as http://:8080/makers.xml and you are done.

Install Apache HTTP Server
Install Apache HTTP Server

You can easily maintain the documents there, update them and as long as the server is accessible use them in an HTTP Filtered Value Set.

Tomcat Solution

With Tomcat it is not quite that easy to create a solution, but if you have Tomcat already installed, once you have a solution, it is just trivial to deploy and use.

1. Install

Install The Web, XML, and Java EE Development Tools as described in the Process Enactment Workshop Lab 5, at the beginning.

Select Help>Install New Software and add an update site. I used the Helios Update Site for RTC 4.0. up to 4.0.3 vanilla zip install. Make sure to pick the right version for your Eclipse version. Select the update site. Select and install the whole package Web, XML, and Java EE Development Tools, not just JavaScript. Restart Eclipse.

I tried to use the Tomcat that comes with RTC for testing, but had issues, so I would suggest to Download a vanilla Tomcat for testing. I used the ZIP version and unpacked it into the folder C:/Apache Tomcat.

Tomcat Installed
Tomcat Installed

2. Create Dynamic Web Project

In your Eclipse RTC Client open the J2EE Perspective. Use File>New>Dynamic Web Project to create a new project.

Create Dynamic Web Project
Create Dynamic Web Project

In the wizard enter a project name. Check the default settings and create a new Target Runtime based on Tomcat v7.0 or whatever version you are using.  As Tomcat Installation Directory provide C:/Apache Tomcat or wherever you installed to. Back in the wizard should show something similar to this image.

Dynamic Web Project Wizard Step 1
Dynamic Web Project Wizard Step 1

Click Next until you reach the wizard page Web Module.

If you want to fix your context root, you can do that now. The context root is the name of the folder in which the data will later be published to the web. It is case-sensitive and you need to remember the name later. In my example my data will be published at HTTPS://:9443/PEWEnactmentData/ once I deploy on my RTC Tomcat. Make sure to choose WebContent or webcontent in the Content Directory. Check Generate web.xml deployment descriptor. See the image below as example.

Dynamic Web Project Wizard Web Module Page
Dynamic Web Project Wizard Web Module Page

Press Finish.

You have now successfully created a Dynamic Web Project, that will later be used to publish the content.  Browse the project. You are only interested in the folder WebContent.

New Web Project
New Web Project

3. Provide The Data

You now need to provide your XML data. Put the file you want to publish into the folder WebContent. To make it easier for users to locate the files I added a file index.html too. This file just has some text that points to the XML files that are hosted. The link is relative as shown in the screenshot below.

Project With Data Ready To Publish
Project With Data Ready To Publish

4. Publish And Test

Now that you are ready to publish and test, select the Project node and use the context menu to run it on your test server.

Run On Server Step 1
Run On Server

In the Wizard check that he correct runtime environment is selected and that the configuration works. Press Next and check your project is Configured to be deployed. Press Finish.

Your Server starts and after a few seconds the index page should come up like below.

Your Web Site
Your Web Site

You can click on the link in your index page to bring up your xml code. If you don’t have an Index.html, you can directly open your XML page. For example using the URL http://localhost:8080/PEWEnactmentData/makers.xml.

Now that everything works, you are ready to export the project and deploy it on your RTC Tomcat server.

5. Create A War File and Deploy

Right Click on your project again. Select Export>WAR file Enter a suitable destination folder. You can directly export into the /server/tomcat/webapps folder if you like. I chose a temporary folder. You can play around with the other options too e.g. if you want to deploy on WAS. Press Finish to run the export.

Export WAR File
Export WAR File

If you have exported to /server/tomcat/webapps you have already also deployed. If not, copy and paste your war file into /server/tomcat/webapps. If the server is running the deployment process starts right away. If not, start the server.

Once the server is up, you should be able to open your web resources using your server URL and the context root you chose. In my example https://localhost:9443/PEWEnactmentData opens the index page and https://localhost:9443/PEWEnactmentData/makers.xml opens the XML file.

Configuring the HTTP Filtered Value Set

Please be aware, that if you use HTTPS with your HTTP Filtered Value Set, you might have to check the check box to Ignore  invalid SSL certification if you did not fix your certificate.


I hope I could show that it is easily possible to store your XML files required for access from an HTTP Filtered Value Set. I have to go now and fix the Process Enactment Workshop.