# JVM toolchain

> Elide's bundled JDK 25 and Kotlin 2.5: compile and run with javac, java and kotlinc, format, build projects, and call the tools from other builds.

Elide bundles JDK 25 and Kotlin 2.5.0-Beta2. Libraries and annotations available to programs: [JVM APIs](https://elide.help/docs/api-jvm).

## Compile and run

```bash
elide javac -- -d out Hello.java
elide java -- -cp out Hello

elide run Hello.kt
```

Options for the wrapped tool go after `--`. `elide run` compiles a Kotlin file and runs it with the Kotlin standard
library; `elide java` does not add it ([Kotlin Compiler](https://elide.help/docs/toolchain/jvm/kotlinc#compile-source-files)).

## Format

```bash
elide format -- src
elide format -- -n src # check only
```

Use `elide format --install -- --jfmt` for the Java jfmt dialect with project dependencies installed before its
[type-based import pass](https://elide.help/docs/toolchain/jvm/formatting#resolve-and-rewrite-imports). Kotlin still uses ktfmt.
Per-formatter options and selections: [Formatting](https://elide.help/docs/toolchain/jvm/formatting).

## Build a project

With an `elide.pkl`:

```bash
elide install
elide build
elide test
```

Sources in `src/main/java`, `src/main/kotlin` and `src/test/…` need no configuration. JVM tests
need an `elide.pkl`. Coverage: [Testing](https://elide.help/docs/toolchain/testing#coverage).

In a terminal, each task line shows how many files it compiles. In CI, with redirected output, or under an agent, the
build prints one plain line per task.

## Rewrite and inspect code

[OpenRewrite](https://elide.help/docs/toolchain/jvm/rewrite) previews and applies recipes to main Java sources.
[Dependency code index](https://elide.help/docs/toolchain/jvm/code-index) finds class origins, inspects members, and queries references in
Maven dependencies and compiled local Java and Kotlin code. Both are experimental in 1.6.0 and use `elide.pkl`.

```bash
elide rewrite org.openrewrite.java.RemoveUnusedImports --dry-run
elide index build --layers=l1,l2,l3
elide index used-by java.util.List
```

## Compile headers and generated code

The compiler wrappers expose separate outputs for build systems that distinguish a library's compile-time API from
its implementation:

```bash
elide javac --abi-only --emit-abi java-abi.jar -- src/Api.java
elide kotlinc --abi-only -- -d kotlin-abi.jar src/Library.kt
```

Dependents can compile against these headers; execution needs the full implementation. Java headers skip method-body
compilation. Kotlin header-only compilation strips non-inline implementation bodies by default while preserving
metadata, inline code and constants needed by consumers. Full compilation can also emit a header alongside its regular
output. See [Java ABI jars](https://elide.help/docs/toolchain/jvm/javac#abi-jars) and
[Kotlin ABI jars](https://elide.help/docs/toolchain/jvm/kotlinc#abi-jars) for output flags and constraints.

For code generation, select the phase that matches the processor or input:

| Input | Command or configuration |
| --- | --- |
| Java annotation processor | `elide javac -- --processor-path …`; [processor setup](https://elide.help/docs/toolchain/jvm/maven#annotation-processors) |
| Java annotation processor over Kotlin declarations | `elide kotlinc --kapt-sources …`; [processing phase](https://elide.help/docs/toolchain/jvm/kotlinc#annotation-processors-over-kotlin) |
| KSP2 symbol processor | `elide kotlinc --ksp-output …`; [KSP outputs and compilation](https://elide.help/docs/toolchain/jvm/kotlinc#kotlin-symbol-processing) |
| C headers | `jvm.java.bindings` or `elide javac -- --jextract …`; [compile bindings in memory](https://elide.help/docs/toolchain/jvm/javac#c-header-bindings) |

Kotlin processing commands generate outputs for a later compile; `elide build` does not schedule KSP or Java annotation
processing over Kotlin automatically. C header bindings selected in a Java source set are generated and compiled by the
normal project build. [Standalone jextract](https://elide.help/docs/toolchain/native/jextract) exports Java FFM sources separately.

## Existing build systems

| Build | Use |
| --- | --- |
| Maven | [Maven plugin](https://elide.help/docs/build-tools-maven), or [`elide mvn`](https://elide.help/docs/toolchain/jvm/native-maven) |
| Gradle | [Gradle plugin](https://elide.help/docs/build-tools-gradle) |
| Bazel | [`rules_elide` and persistent workers](https://elide.help/docs/build-tools-bazel) |
| Any | `elide javac -- …` and the other wrappers, or `JAVA_HOME` set to the Elide distribution |

Overview: [Build tool integration](https://elide.help/docs/build-tools).

`elide --help-all` lists every command.

## Samples

- [Java records and streams](https://elide.help/docs/code-samples#java-records-and-streams)
- [Kotlin collections](https://elide.help/docs/code-samples#kotlin-collections)
- [Kotlin tests](https://elide.help/docs/code-samples#kotlin-tests)

Start from a template:

```bash
elide init --template java        # Java app with a JUnit test
elide init --template ktjvm       # Kotlin app with a test
elide init --template workspace   # Kotlin library and app in one workspace
```
