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
Automatic Creation (Recommended)
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.yamlfile 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
- Use relative paths when possible - the project command automatically converts absolute paths to relative paths when they are within the output directory
- Include all relevant packages in each module to ensure complete analysis
- 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