Introduction

This document describes the usage of Adabu.

Requirements

The following steps have been tested under Gentoo, Debian and MacOS 10.5. In theory, the tool should also work under Windows, however, we never tested if it actually does.

Overview

Adabu currently consists of two command line tools, which (1) trace the execution of a program and (2) analyze the trace to learn object behavior models. The following sections provide details on how to invoke these two tools.

An illustrating example

Throughout this document, we will illustrate each step using a small artificial example consisting of two Java classes Test and Foo , where Test contains the main method and simply creates and instance of Foo .

  1 package test;
  2 
  3 public class Test {
  4   public static void main(String[] args) {
  5     Foo foo = new Foo();
  6     foo.bar();
  7 
  8   }
  9 }
  1 package test;
  2
  3 public class Foo {
  4   int state = 0;
  5   public Foo() {
  6     state = 1;
  7     System.out.println("Foo constructor.");
  8   }
  9
 10   public void bar() {
 11     state = 2;
 12     System.out.println("Foo.bar");
 13   }
 14 }

Note: You can download these files here .

Getting Started

To get started, you first have to install Adabu:

  1. Make sure that you have Java 1.6 installed and ready to run.
  2. Go to the Downloads page and download the most recent version of the tracing component and Adabu itself.
  3. Both the tracer and Adabu come with ready-to-use bash scripts located in folder bin . To use the tracer script, you have to edit it and configure the installation directory manually. The corresponding variable can be found in the second line in all scripts. The adabu script needs to be run from the installation directory (for version 0.5 this is adabu-cli-0.5).

For the remainder of this file, we assume that Adabu is installed in folder $ADABU_INSTALL,the tracer is installed in $TRACER_INSTALL and the example is installed in $EXAMPLE_INSTALL .

Step 1: Tracing a Run

To trace a program run, you can use the tracerun.sh script of the tracer. Make sure that you changed the installation directory. The tracer is implemented as a Java bytecode agent . The tracerun.sh script basically builds a command line that invokes Java with some special parameters that activate the tracer. To trace the example, we first need to compile it and can then invoke the tracer as follows.

  $TRACER_INSTALL/bin/tracerun.sh -cp $TRACER_INSTALL test.Test

This generates the following output:

Foo constructor.
Foo.bar

By default, the tracer stores the trace in a file name trace.out in the working directory. To change that, you can pass a parameter -Dadabu2.resultFilename . For example, to store the trace in file /tmp/trace.ser , you can use the following call:

  $TRACER_INSTALL/bin/tracerun.sh -Dadabu2.resultfilename=/tmp/trace.ser -cp $TRACER_INSTALL test.Test

If everything went well, you should now have a trace file of roughly 70 mega bytes.

Step 2: Mining Models

In the next step, we will mine a model for test.Foo from the trace file. To that end, we will use the command line interface to Adabu. In $ADABU_INSTALL, you can find a bash script to invoke the tool. It's usage is as follows:

usage: Adabu
 -abstractStates           Boolean flag if state abstraction for models is
                           used (defaults to true)
 -appClassPath <path>      Java class path for all classes that belong to
                           the application.
 -heapPathLength <int>     Maximum length of heap paths when mining models
                           (expert users, defaults to 1)
 -resultDirectory <file>   Result directory (will be created if it does
                           not exist, and cleaned if it does exist)
 -traceFile <file>         Name of the trace file.
 -types <list>             A list of fully qualified class names for which
                           to mine models separated by hash signs (#)

In my case, I need to invoke Adabu as follows:

cd $ADABU_INSTALL
bin/runadabu.sh -traceFile ~/tmp/trace.ser \
                -resultDirectory ~/tmp/results \
                -types test/Foo 
                -appClassPath /Users/dallmeier/tmp

When specifying the parameters, you have to be aware of the following things:

traceFile The location of the trace file may be different on your system.
resultDirectory The result directory is created if it does not exist, and cleaned without any warnings if it already exists.
types You can specify more than one class by separating them with hash signs (#). Be aware that the separator for package names is / (slash) and not (.), as required by the Java Virtual Machine.
appClassPath A java class path specification for all classes that are part of the application that we run. In our case, I simply specify the folder where the test package of the example resides.

If all went well, the tool will show the following output:

[INFO ] 2011-04-07 12:38:32,291: Cleaning existing result directory /Users/dallmeier/tmp/results
[INFO ] 2011-04-07 12:38:32,578: Accepted types for model mining: [test/Foo]
[INFO ] 2011-04-07 12:38:32,578: Running model miner.
[DEBUG] 2011-04-07 12:38:37,188: 01% done.
...
[DEBUG] 2011-04-07 12:38:46,581: 97% done.
[INFO ] 2011-04-07 12:38:46,902: Mined a total of 1 models.
[INFO ] 2011-04-07 12:38:46,903: Running state abstraction.
[INFO ] 2011-04-07 12:38:48,701: Saving results to directory /Users/dallmeier/tmp/results

For each instance of a type specified by the type parameter, Adabu will create two files that store the object behavior model. In our case, we end up with two files:

test.Foo_0.ser
test.Foo_0.dot

The file names consist of the class name (in this case separated by dots because slashes won't work under unix), followed by a counter for each instance of the class. The model is stored twice: The .ser file contains a serialized instance of de.unisaarland.cs.st.adabu.trans.model.TransitiveObjectModel , and the .dot file contains a version of the model in the dot format (see http://www.graphviz.org/ ). For me, the content of test.Foo_0.dot is as follows:

  1 digraph automaton {
  2         page="9,11";
  3         size="9,11";
  4         0 -> 1 [label="<init>()V{0=6809}"];
  5         1 -> 2 [label="bar()V{0=6809}"];
  6         0 [label=""];
  7         1 [label="state: 1"];
  8         2 [label="state: 2"];
  9 }

The object behavior model has three states. The state labels summarize the values of all fields for this instance of Foo , and the transition labels give the signatures of the methods that caused the state transitions.

Getting the list of types from a trace file

If you are unsure about what types to mine models for, you can use the type extraction utility to get a list of all types for which the trace file contains at least one instantiation. To that end, you can use the extracttypes.sh script provided with Adabu:

usage: InstantiatedTypesExtractor
 -resultFile <file>   Result file.
 -traceFile <file>    Name of the trace file.

This utility takes as input a trace file and writes a result file where each line contains one type for which the trace file contains data. In my setting, to analyze the trace file and find all types, I enter the following:

cd $ADABU_INSTALL
bin/runadabu.sh -traceFile ~/tmp/trace.ser \
                -resultFile ~/tmp/types.list

Output of the tool looks as follows:

[DEBUG] 2011-04-12 10:13:56,139: 01% done.
...
[DEBUG] 2011-04-12 10:14:02,179: 97% done.
[ INFO ] 2011-04-12 10:14:02,336: Wrote a list of 71 types to file /Users/dallmeier/tmp/adabu-cli-0.5/../types.list

And the results are:

dhcp-137:tmp dallmeier$ cat types.list 
com/apple/java/Application$1
com/apple/java/Usage$3
java/io/BufferedInputStream
java/io/File
java/io/FileInputStream
java/io/ObjectStreamField
java/lang/Object
java/lang/String
java/lang/StringBuffer
java/lang/StringBuilder
java/lang/ref/WeakReference
java/math/BigInteger
java/math/MutableBigInteger
java/math/SignedMutableBigInteger
java/net/Parts
java/net/UnknownContentHandler
java/nio/HeapByteBuffer
java/nio/HeapCharBuffer
java/security/AlgorithmParameters
java/security/BasicPermissionCollection
java/security/KeyFactory
java/security/MessageDigest$Delegate
java/security/Permissions
java/security/Policy$UnsupportedEmptyCollection
java/security/ProtectionDomain$2
java/security/ProtectionDomain$Key
java/security/Provider$EngineDescription
java/security/Provider$Service
java/security/Provider$ServiceKey
java/security/Provider$UString
java/security/Security$1
java/security/Signature$Delegate
java/security/cert/CertificateFactory
java/text/Normalizer$Form
java/util/AbstractList$Itr
java/util/AbstractList$ListItr
java/util/ArrayList
java/util/Collections$UnmodifiableCollection
java/util/Collections$UnmodifiableCollection$1
java/util/Collections$UnmodifiableRandomAccessList
java/util/HashMap
java/util/HashMap$Entry
java/util/HashMap$EntryIterator
java/util/HashMap$EntrySet
java/util/Hashtable
java/util/Hashtable$Entry
java/util/IdentityHashMap$KeyIterator
java/util/IdentityHashMap$KeySet
java/util/LinkedHashMap
java/util/LinkedHashMap$Entry
java/util/LinkedHashMap$EntryIterator
java/util/LinkedList$Entry
java/util/Properties
java/util/Properties$LineReader
java/util/RandomAccessSubList
java/util/SubList$1
java/util/concurrent/ConcurrentHashMap
java/util/concurrent/ConcurrentHashMap$HashEntry
java/util/concurrent/ConcurrentHashMap$Segment
java/util/concurrent/locks/ReentrantLock$NonfairSync
java/util/regex/Matcher
java/util/regex/Pattern
java/util/regex/Pattern$5
java/util/regex/Pattern$LastNode
java/util/regex/Pattern$Node
java/util/regex/Pattern$Single
java/util/regex/Pattern$Start
java/util/regex/Pattern$TreeInfo
sun/security/action/GetPropertyAction
sun/security/jca/ServiceId
test/Foo

Note: Depending on the virtual machine you are using, you may get different java and sun classes. However, test/Foo should always be part of the result.

Questions

If you have comments or run into problems with Adabu, please don't hesitate to send an email to dallmeier@cs.uni-saarland.de .