# Maven plugin

> Compile Java and Kotlin in an existing Maven build with Elide's javac and kotlinc: the elide-maven-plugin, the Kotlin drop-in, and the compilerId-only setup.

Adding `dev.elide:elide-maven-plugin` to a `pom.xml` makes the build compile Java with `elide javac` and Kotlin
with `elide kotlinc`. Maven keeps dependency resolution, tests, packaging and every other plugin.

## Requirements

| | Version |
| --- | --- |
| Maven | 3.9 or later |
| JDK running Maven | 11 or later |
| Elide | 1.6 or later |

Elide must be on `PATH`, or set `<executable>` (see [Configuration](#configuration)).

## Choose an artifact

| Artifact | Use when | Compiles |
| --- | --- | --- |
| `elide-maven-plugin` | New setup, Java and Kotlin | Java and Kotlin |
| `elide-kotlin-maven-plugin` | The build already uses `kotlin-maven-plugin` | Kotlin; Java through `maven-compiler-plugin` |
| `elide-java-compiler` | Only Java, keeping `maven-compiler-plugin` as is | Java |

All three are in Maven Central under `dev.elide`, version `1.0.0`.

## Install

```xml
<build>
  <plugins>
    <plugin>
      <groupId>dev.elide</groupId>
      <artifactId>elide-maven-plugin</artifactId>
      <version>1.0.0</version>
      <extensions>true</extensions>
    </plugin>
  </plugins>
</build>
```

`<extensions>true</extensions>` is required: it replaces the default compile bindings. With it, the plugin adds
`src/main/kotlin` and `src/test/kotlin` as source roots and a `kotlin-stdlib` dependency when the POM declares none.

To replace `kotlin-maven-plugin` in place, change its coordinates to `dev.elide:elide-kotlin-maven-plugin:1.0.0` and keep
its configuration; it accepts the same parameters.

For Java only, without a new plugin:

```xml
<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.15.0</version>
  <dependencies>
    <dependency>
      <groupId>dev.elide</groupId>
      <artifactId>elide-java-compiler</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>
  <configuration>
    <compilerId>elide</compilerId>
  </configuration>
</plugin>
```

## Goals

With extensions on, the goals bind to the lifecycle; nothing needs an `<execution>`.

| Goal | Phase | Runs |
| --- | --- | --- |
| `elide:kapt` | `process-sources` | Skipped unless annotation processors are configured |
| `elide:compile-kotlin` | `compile` | `elide kotlinc` on main sources |
| `elide:compile` | `compile` | `elide javac` on main sources, after Kotlin |
| `elide:test-kapt` | `process-test-sources` | Skipped unless annotation processors are configured |
| `elide:test-compile-kotlin` | `test-compile` | `elide kotlinc` on test sources |
| `elide:test-compile` | `test-compile` | `elide javac` on test sources |

`elide-kotlin-maven-plugin` has the same goals without the Java ones, under the prefix `elide-kotlin`.

## Configuration

Every `maven-compiler-plugin` and `kotlin-maven-plugin` parameter applies (`<release>`, `<compilerArgs>`, `<args>`,
`<jvmTarget>`, …). One parameter is added:

| Parameter | Default | Effect |
| --- | --- | --- |
| `executable` | `elide` on `PATH` | Path to the `elide` binary |

```xml
<plugin>
  <groupId>dev.elide</groupId>
  <artifactId>elide-maven-plugin</artifactId>
  <version>1.0.0</version>
  <extensions>true</extensions>
  <configuration>
    <executable>/opt/elide/bin/elide</executable>
  </configuration>
</plugin>
```

With `elide-java-compiler`, set `<executable>` in the `maven-compiler-plugin` configuration instead.

## Example

A project with a Kotlin object, a Java main class and a JUnit test:

```text
pom.xml
src/main/kotlin/com/example/Greeter.kt
src/main/java/com/example/Hello.java
src/test/java/com/example/GreeterTest.java
```

```xml
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>hello</artifactId>
  <version>1.0.0</version>

  <properties>
    <maven.compiler.release>21</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.13.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>dev.elide</groupId>
        <artifactId>elide-maven-plugin</artifactId>
        <version>1.0.0</version>
        <extensions>true</extensions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.5.4</version>
      </plugin>
    </plugins>
  </build>
</project>
```

```bash
mvn package
```

```terminaloutput
[INFO] Added kotlin-stdlib dependency, version 2.3.21
[INFO] --- elide:1.0.0:kapt (default-kapt) @ hello ---
[INFO] No annotation processors configured, skipping kapt
[INFO] --- elide:1.0.0:compile-kotlin (default-compile-kotlin) @ hello ---
[INFO] ✅  Kotlin sources compiled to `classes` (1.3s)
[INFO] --- elide:1.0.0:compile (default-compile) @ hello ---
[INFO] Compiling 1 source file with elide [forked debug release 21] to target/classes
[INFO] --- elide:1.0.0:test-compile (default-test-compile) @ hello ---
[INFO] Compiling 1 source file with elide [forked debug release 21] to target/test-classes
[INFO] --- surefire:3.5.4:test (default-test) @ hello ---
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- jar:3.5.0:jar (default-jar) @ hello ---
[INFO] Building jar: target/hello-1.0.0.jar
[INFO] BUILD SUCCESS
```

## OpenRewrite and dependency queries

For projects with an `elide.pkl`, see [OpenRewrite](https://elide.help/docs/toolchain/jvm/rewrite) and
[Dependency code index](https://elide.help/docs/toolchain/jvm/code-index). The compiler plugin does not add rewrite or code-index goals
or pass Maven's resolved dependency graph to those commands. See
[the project setup boundary](https://elide.help/docs/build-tools#openrewrite-and-dependency-queries) before using them alongside Maven.

## Limits

- kapt does not run: a `kapt` execution with annotation processors configured fails.
- Kotlin compiler plugins (`<compilerPlugins>`) other than all-open, no-arg, sam-with-receiver, assignment and Lombok
  fail with a compiler error.
- The added `kotlin-stdlib` is version 2.3.21; declare `kotlin-stdlib` yourself to pick another.
- Each compile runs a new `elide` process; there is no shared compiler daemon between modules.

To run the whole Maven build natively instead, see [POM export and native Maven](https://elide.help/docs/build-tools-export). To leave Maven,
see [Adopt an existing project](https://elide.help/docs/toolchain/usage/adopt).
