ProjectBuildStage

Stage 1 of the LST classpath-resolution pipeline: extract the project's compile classpath by invoking its own build tool (Maven or Gradle).

Why Stage 1? The most accurate way to obtain the exact JAR set the project actually compiles against is to ask the build tool itself. This accounts for BOM imports, version catalogs, dependency management, and plugin-contributed dependencies that are difficult to reproduce by static parsing alone.

Build tool detection: The presence of pom.xml signals a Maven project; any of build.gradle, build.gradle.kts, or settings.gradle(.kts) signals a Gradle project. If neither is found, extractClasspath returns null immediately.

Maven: Runs mvnw dependency:build-classpath (using the Maven wrapper if present, otherwise mvn). The classpath is written to a temp file via -Dmdep.outputFile and then parsed. The test scope is included (-DincludeScope=test) so test-only dependencies are available when recipes analyse test sources.

Gradle: Injects a temporary Gradle init script that registers a printClasspathForOpenRewrite task. The task resolves the project's testRuntimeClasspath (falling back through runtimeClasspath, testCompileClasspath, compileClasspath, and default in that order) and prints each JAR path to stdout. The Gradle wrapper (gradlew) is used when present; otherwise the system gradle command is used.

Failure behaviour: Any failure — non-zero exit code, process timeout, missing build tool, or an unexpected exception — is logged as a warning and causes extractClasspath to return null. The pipeline then falls through to DependencyResolutionStage (Stage 2).

Compilation: After a successful Stage 1, tryCompile is called if the project has no pre-compiled class directories. Compiled .class files are then appended to the classpath so that intra-project type references (e.g. wildcard imports across packages within the same project) resolve correctly instead of appearing as JavaType.Unknown during recipe execution.

Extensibility: The class is open with open methods so tests can subclass it to inject a fake classpath without spawning real processes.

Constructors

Link copied to clipboard
constructor(logger: RunnerLogger)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
open fun extractClasspath(projectDir: Path): List<Path>?

Attempts to extract the project's compile classpath by invoking the build tool.

Link copied to clipboard
open fun tryCompile(projectDir: Path): Boolean

Attempts to compile the project using its build tool.