Fundamentals 14 min read

An Introduction to SootUp: Static Analysis of JVM Code

This article introduces the SootUp library, explains how to configure its Maven dependencies, describes the Jimple intermediate representation, and demonstrates how to use SootUp's API to analyze Java source code, bytecode, and method bodies through a series of code examples.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
An Introduction to SootUp: Static Analysis of JVM Code

1. Content

This article provides an in‑depth analysis of the SootUp library, a tool for static analysis of JVM code that can handle both raw source code and compiled bytecode, representing a major redesign of the original Soot library with improvements in modularity, testability, maintainability, and usability.

2. Dependency Configuration

Before using SootUp you must add the latest version (1.3.0 at the time of writing) to your build. The following Maven dependencies are required:

<dependency>
  <groupId>org.soot-oss</groupId>
  <artifactId>sootup.core</artifactId>
  <version>1.3.0</version>
</dependency>
<dependency>
  <groupId>org.soot-oss</groupId>
  <artifactId>sootup.java.core</artifactId>
  <version>1.3.0</version>
</dependency>
<dependency>
  <groupId>org.soot-oss</groupId>
  <artifactId>sootup.java.sourcecode</artifactId>
  <version>1.3.0</version>
</dependency>
<dependency>
  <groupId>org.soot-oss</groupId>
  <artifactId>sootup.java.bytecode</artifactId>
  <version>1.3.0</version>
</dependency>
<dependency>
  <groupId>org.soot-oss</groupId>
  <artifactId>sootup.jimple.parser</artifactId>
  <version>1.3.0</version>
</dependency>

The dependencies serve the following purposes:

org.soot-oss:sootup.core – core component of the SootUp library.

org.soot-oss:sootup.java.core – core module specialized for the Java language.

org.soot-oss:sootup.java.sourcecode – analyzes Java source code.

org.soot-oss:sootup.java.bytecode – focuses on analyzing compiled Java bytecode.

org.soot-oss:sootup.jimple.parser – parses Jimple, the intermediate language used by SootUp.

SootUp does not provide a BOM (Bill of Materials), so each dependency version must be managed manually.

3. What is Jimple?

SootUp can analyze multiple code formats, including Java source, compiled bytecode, and even JVM internal classes, by converting them into an intermediate representation called Jimple. Jimple presents Java code in a variable‑based, three‑address form that is easier to analyze than the stack‑based bytecode or the nested structure of source code.

For example, the following Java method:

public void demoMethod() {
    System.out.println("Inside method.");
}

can be represented in Jimple as:

public void demoMethod() {
    java.io.PrintStream $stack1;
    target.exercise1.DemoClass this;

    this := @this: target.exercise1.DemoClass;
    $stack1 = <java.lang.System: java.io.PrintStream out>;

    virtualinvoke $stack1.<java.io.PrintStream: void println(java.lang.String)>("Inside method.");
    return;
}

Although more verbose, the Jimple form retains the same functionality and can be directly parsed or generated by SootUp, facilitating storage and transformation of code in this representation.

4. Code Analysis

To analyze code you first create an AnalysisInputLocation and build a JavaView around it. Various input locations are available:

JrtFileSystemAnalysisInputLocation – analyzes JVM classes directly from the runtime file system.

OTFCompileAnalysisInputLocation – analyzes source files, either from a path or from a string in memory.

JavaClassPathAnalysisInputLocation – analyzes compiled bytecode from a class‑path directory or JAR file.

AnalysisInputLocation inputLocation = new JrtFileSystemAnalysisInputLocation();
AnalysisInputLocation inputLocation = new OTFCompileAnalysisInputLocation(
    Path.of("src/test/java/com/baeldung/sootup/AnalyzeUnitTest.java"));
AnalysisInputLocation inputLocation = new OTFCompileAnalysisInputLocation(
    "AnalyzeUnitTest.java", javaContents);
AnalysisInputLocation inputLocation = new JavaClassPathAnalysisInputLocation("target/classes");

Once an AnalysisInputLocation is created, a JavaView can be instantiated:

JavaView view = new JavaView(inputLocation);

The view provides access to all types present in the input.

5. Accessing Class Information

After constructing a JavaView , you can retrieve a class by its fully qualified name using the IdentifierFactory :

IdentifierFactory identifierFactory = view.getIdentifierFactory();
ClassType javaClass = identifierFactory.getClassType("com.baeldung.sootup.ClassUnitTest");
Optional<JavaSootClass> sootClass = view.getClass(javaClass);

If the class is guaranteed to exist, getClassOrThrow() returns a SootClass directly:

SootClass sootClass = view.getClassOrThrow(javaClass);

From the SootClass you can inspect modifiers, super‑classes, interfaces, fields, and methods.

6. Accessing Fields and Methods

Given a SootClass , you can list its fields and methods:

Set<? extends SootField> fields = sootClass.getFields();
Set<? extends SootMethod> methods = sootClass.getMethods();

Specific members can be accessed by name (and parameter types for methods):

Optional<? extends SootField> field = sootClass.getField("aField");
Optional<? extends SootMethod> method = sootClass.getMethod("someMethod", List.of());
Optional<? extends SootMethod> overloaded = sootClass.getMethod("anotherMethod", List.of(identifierFactory.getClassType("java.lang.String")));
Set<? extends SootMethod> allSameName = sootClass.getMethodsByName("someMethod");

7. Analyzing Method Bodies

With a SootMethod you can obtain its Body and explore locals, statements, and the control‑flow graph.

Body methodBody = sootMethod.getBody();
Set<Local> methodLocals = methodBody.getLocals();
StmtGraph<?> stmtGraph = methodBody.getStmtGraph();
List<Stmt> stmts = stmtGraph.getStmts();

Locals include the implicit this reference, method parameters, and compiler‑generated temporaries. The statement graph shows each Jimple statement, such as JIdentityStmt , JAssignStmt , JInvokeStmt , and JReturnVoidStmt , making the execution flow explicit.

8. Summary

This quick introduction covered the purpose of SootUp, how to configure its dependencies, the role of Jimple as an intermediate representation, and the basic API for creating analysis input locations, navigating classes, fields, methods, and method bodies. The library offers many more advanced features for deeper Java code analysis.

JavaJVMBytecodeStatic AnalysislibraryJimpleSootUp
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.