This document describes the usage of Adabu.
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.
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.
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 .
To get started, you first have to install Adabu:
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 .
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.
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.
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.
If you have comments or run into problems with Adabu, please don't hesitate to send an email to dallmeier@cs.uni-saarland.de .