# Java Compiler

> Compile Java 25 source with elide javac or in a project build.

## Compile source files

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

<img src="https://elide.help/assets/demos/javac.gif" alt="Compiling and running Java source with Elide" width="1591" height="728" loading="lazy" decoding="async" class="rounded-lg border border-border my-6 w-full" />

`javac` options go after `--`. Without `-d`, class files are written beside their sources. `elide javac -- -help` lists
every `javac` option.

## Elide options

Elide options go before `--`:

| Option | Purpose |
| --- | --- |
| `--jar PATH` | Pack the output into a JAR at `PATH`. |
| `--manifest FILE` | Manifest for the `--jar` output. |
| `--max-errors N` | Errors shown before the rest are counted; `0` shows all. Warnings are de-duplicated and never limited. |
| `--report-used-deps PATH` | Write the classpath entries the output references (Bazel strict deps). |
| `--capabilities` | Print compiler capabilities as JSON. |
| `--persistent_worker` | Run as a Bazel persistent worker, singleplex or multiplex. |
| `--classpath-cache` | Worker only: reuse classpath state across compiles. `ELIDE_WORKER_CLASSPATH_CACHE=0` turns it off. |

```bash
elide javac --jar target/app.jar -- src/Main.java src/Util.java
elide javac --jar target/app.jar --manifest src/MANIFEST.MF -- src/Main.java
```

## Build projects

`elide build` compiles `src/main/java` and `src/test/java`, or the [source sets](https://elide.help/docs/toolchain/source-sets) the manifest
declares. To run only main Java compilation:

```bash
elide build compile-java-main
```

```pkl
jvm {
  target = 25
  java {
    release = 25
    compiler {
      mode = "embedded"
      flags { "-Xlint:all" }
    }
  }
  features {
    graalvm = false
  }
}
```

| Property | Meaning | Default |
| --- | --- | --- |
| `jvm.target` | Bytecode target; the `--release` level when `java.release` is unset. | `"auto"` (21) |
| `jvm.java.release` | `--release` level: compile against that JDK's API only. | `"auto"` |
| `jvm.java.source` | Use `--source`/`--target` instead of `--release`; ignored when `release` is set. | `"auto"` |
| `jvm.java.compiler.mode` | `"embedded"` uses Elide's `javac`; `"external"` runs the one in `jvm.javaHome`. | `"embedded"` |
| `jvm.java.compiler.flags` | Extra `javac` flags; `--release`, `-source` or `-target` here replaces Elide's. | none |
| `jvm.javaHome` | Java home for external compiles and forked JVMs. | Elide's own |
| `jvm.debug` | Compile with `-g`. | `true` |
| `jvm.features.graalvm` | Put `org.graalvm.nativeimage`, `word` and `collections` on the compile classpath. | `false` |
| `jvm.features.automodules` | Put JARs without a module descriptor on the module path as automatic modules. | `true` |

The `--release` level is `java.release`, else `jvm.target`, else 21. Each compile writes its arguments to
`javac.args` beside its output. Annotation processors: [Maven Dependencies](https://elide.help/docs/toolchain/jvm/maven#annotation-processors).
