Precompiled Classes and JARs Analysis

July 2, 2026 ยท View on GitHub

OpenTaint supports analyzing pre-compiled Java classes and JARs through a project.yaml configuration file. This enables security analysis when you cannot compile the project due to unavailable build environment, or when working with compiled bytecode only.

File Structure

A project model groups one or more per-language projects under a top-level wrapper:

projectRoot: /path/to/project  # optional
javaProjects:
  - sourceRoot: /path/to/source/root
    javaToolchain: /path/to/java/toolchain  # optional
    modules:
      - moduleSourceRoot: /path/to/module1/src
        packages:
          - com.example.module1
          - com.example.shared
        moduleClasses:
          - /path/to/module1/classes
          - /path/to/module1/target/classes
      - moduleSourceRoot: /path/to/module2/src
        packages:
          - com.example.module2
        moduleClasses:
          - /path/to/module2.jar
    dependencies:  # optional
      - /path/to/dependency1.jar
      - /path/to/dependency2.jar
goProjects:  # optional
  - projectDir: /path/to/go/module

Empty lists and unset optional fields are omitted from the generated file (so a Java-only model has no goProjects, and vice versa).

Field Descriptions

projectRoot (optional)

Root directory of the analyzed project. When the model is generated in portable mode, the paths inside it are stored relative to this directory so the whole model directory can be moved.

javaProjects

List of Java projects. Each entry describes one Java project (a multi-module build is a single entry with several modules; independent builds are separate entries).

Java project fields

  • sourceRoot (required): The root directory containing the project's source code (absolute or relative).
  • javaToolchain (optional): Path to the Java toolchain directory. If omitted, the system's default Java installation is used.
  • modules (required): Array of module configurations. Each module represents a logical unit of the project; at least one is required.
    • moduleSourceRoot (required): Path to the module's source code directory
    • packages (required): List of Java packages contained in this module
    • moduleClasses (required): List of paths to compiled classes or JAR files for this module
  • dependencies (optional): Array of paths to JAR files the project depends on (typically third-party libraries).

goProjects (optional)

List of Go projects. Each entry has a single field, projectDir, pointing at the Go module directory.

Legacy format

For backward compatibility, a flat single-Java-project layout is still accepted as input โ€” the top-level sourceRoot, javaToolchain, modules, and dependencies fields written directly (without the javaProjects wrapper). It is loaded as a project model containing one Java project. New models are generated in the wrapped format shown above.

Creating project.yaml

The compile command automatically creates project.yaml during compilation:

opentaint compile /path/to/java/project --output ./project-model

This generates a complete project model in an output directory with the correct project.yaml configuration.

Manual Creation for Pre-compiled Projects

If you already have compiled classes or JARs, use the project command to create project.yaml:

opentaint project --output ./path/to/project --source-root /path/to/sources \
  --classpath /path/to/app.jar \
  --package com.example.app \
  --dependency /path/to/lib/commons-lang3.jar

Command Flags

  • --output: Output directory for project.yaml (required)
  • --source-root: Source root directory (required)
  • --classpath: Classpath entries (classes or JAR files, required, can be specified multiple times)
  • --package: Java packages (required, can be specified multiple times)
  • --dependency: Project dependencies (JAR files, optional)

Path Resolution

The project command intelligently handles path resolution:

  • All input paths are converted to absolute paths for validation
  • When generating project.yaml, paths are converted to relative paths if they are within the output directory
  • This ensures the project.yaml file is portable when the entire project model directory is moved

Examples

Single Module Project

opentaint project --output . --source-root . \
  --classpath target/classes \
  --package com.example.myapp

Multi-Module Project with Dependencies

opentaint project --output . --source-root . \
  --dependency lib/spring-boot-starter-web-3.2.0.jar \
  --dependency lib/jackson-core-2.15.2.jar \
  --classpath module-core/target/classes \
  --classpath module-web/target/classes \
  --package com.example.core \
  --package com.example.web \
  --package com.example.controller

Using Pre-built JARs

opentaint project --output . --source-root src \
  --classpath dist/myapp.jar \
  --classpath dist/mylib.jar \
  --package com.example.service

Usage with Scan Command

Once you have a project.yaml file, you can scan your project model directly:

opentaint scan --project-model /path/to/project

The --project-model flag tells the scan command to use the provided project model as-is, skipping compilation.

Best Practices

  1. Use relative paths when possible - the project command automatically converts absolute paths to relative paths when they are within the output directory
  2. Include all relevant packages in each module to ensure complete analysis
  3. Specify all dependencies that your code references to avoid missing symbols

Common Use Cases

Maven Project

opentaint project --output . --source-root . \
  --classpath target/classes \
  --package com.example.app \
  --dependency ~/.m2/repository/org/springframework/spring-core/6.0.0/spring-core-6.0.0.jar

Gradle Project

opentaint project --output . --source-root . \
  --classpath build/classes/java/main \
  --package com.example.app \
  --dependency build/libs/dependencies/guava-32.1.2-jre.jar

Legacy Project with Multiple JARs

opentaint project --output . --source-root src \
  --classpath dist/app.jar \
  --classpath dist/utils.jar \
  --package com.legacy.app \
  --dependency lib/commons-io-2.11.0.jar