# Micronaut

> Build, test, package, and compile Java Micronaut applications with Elide, using Pkl or authored resources for configuration.

Elide 1.6.3 installs Micronaut's Java annotation processors, compiles bean definitions, and builds JVM
applications and Native Image executables. Application configuration can live in `elide.pkl` or ordinary resources.

## Start a new application

Generate a Java application with a runnable JVM distribution and an optional context test:

```shell
elide init --plain --skip-defaults --skip-run --template micronaut project_name=my-app
elide install
elide build :app
elide test
elide run
```

Run initialization in an empty project directory. Use `package=dev.acme` and `main_class=Application` to customize
Java names, or `tests=false` to omit the test. See [Project setup](https://elide.help/docs/projects) for interactive initialization.

## Declare dependencies

Use the **Micronaut Core version**, which can differ from the platform BOM version:

```pkl
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm

dependencies {
  micronaut {
    version = "4.10.23"
    modules { "runtime" }
  }
}
jvm { main = "example.Application" }
artifacts {
  ["classes"] = new Jvm.Jar { name = "example" }
  ["app"] = new Jvm.JvmApplication {
    name = "example"
    from { "classes" }
  }
}
```

Create `src/main/java/example/Application.java`:

```java
package example;

import io.micronaut.context.ApplicationContext;

public final class Application {
  public static void main(String[] args) {
    try (ApplicationContext context = ApplicationContext.run()) {
      System.out.println(context.getProperty("sample.message", String.class).orElse("hello"));
    }
  }
}
```

Module names expand to `io.micronaut:micronaut-<name>:<version>`. Add `http-server-netty` for a Netty
HTTP server; `testModules` adds Core modules to test dependencies. Independently versioned libraries,
such as Micronaut Serialization and Micronaut Test, use ordinary [Maven coordinates](https://elide.help/docs/toolchain/jvm/maven).

```bash
elide install
elide build :app
elide run
```

Elide installs matching `micronaut-inject-java` and `micronaut-graal` processors. Direct Core coordinates
also activate this behavior, after workspace version pins are applied. Conflicting Core or processor versions
fail validation. Transitive-only framework dependencies and satellite coordinates cannot establish a Core version;
declare a Core module or use the shorthand.

## Configure the application in Pkl

Add this block to the manifest:

```pkl
jvm {
  micronaut {
    config {
      micronaut { application { name = "example" } }
      sample {
        message = "hello"
        number = 7
        enabled = true
        labels = new Listing { "alpha"; "beta" }
      }
    }
  }
}
```

`config` accepts arbitrary JSON-compatible objects, mappings, lists, strings, numbers, booleans, and nulls.
Pkl evaluates the values and renders `application.json`; there is no fixed list of supported Micronaut settings.
Elide installs the matching `micronaut-jackson-core` JSON loader automatically.

The generated file is placed on production classpaths and in production JARs. Editing the Pkl values invalidates
resource and JAR tasks, and downstream native builds consume the updated JAR. Micronaut's normal environment
and system-property overrides remain available. Configuration packaged into a JAR or executable is readable by
its recipients; supply deployment secrets at runtime.

## Use resources instead

Omit `jvm.micronaut` and put `application.json`, `application.yml`, or `application.properties` in
`src/main/resources`. Declare the loader required by the chosen format. For JSON:

```pkl
dependencies {
  maven {
    packages { "io.micronaut:micronaut-runtime:4.10.23" }
    runtimeOnly { "io.micronaut:micronaut-jackson-core:4.10.23" }
  }
}
```

An authored `application.json` and generated Pkl configuration cannot occupy the same resource path; Elide fails
the build with a collision message. Environment-specific resources such as `application-test.json` can coexist
with generated base configuration. [Source sets](https://elide.help/docs/toolchain/source-sets) control resource roots and destinations.

## Generated outputs

All build outputs stay under the project's build directory, `.dev/` by default:

| Output | Location |
| --- | --- |
| Java classes and processor metadata | `.dev/jvm/classes/main/java/` |
| Processor-generated Java sources | `.dev/jvm/generated-sources/main/java/` |
| Staged configuration | `.dev/staging/jvm-resources/main/` |
| JVM distribution | `.dev/artifacts/install/example/` |
| Native executable and argument record | `.dev/artifacts/native-image/` |

Micronaut generates bytecode for bean definitions and may produce no Java source files. Its `META-INF/micronaut`
and `META-INF/native-image` metadata travel with the compiled classes into the JAR. Generated output never needs
to be copied into `src/` or checked in.

## Tests and coverage

Put JUnit tests in `src/test/java`. The bundled JUnit APIs and runner work with an ordinary Micronaut context:

```java
import io.micronaut.context.ApplicationContext;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class ConfigurationTest {
  @Test
  void readsConfiguration() {
    try (ApplicationContext context = ApplicationContext.run()) {
      assertEquals("hello", context.getRequiredProperty("sample.message", String.class));
    }
  }
}
```

```bash
elide test
elide test --coverage
```

Main resources are available to tests, and annotation processing also runs on test sources. For `@MicronautTest`,
declare `io.micronaut.test:micronaut-test-junit5` with its own compatible version in `maven.testPackages`.
[Testing](https://elide.help/docs/toolchain/testing) describes test selection, XML reports, coverage formats, and exclusions. Reports
use the normal `.dev/reports/tests/` and `.dev/reports/coverage/jvm/` directories. Coverage measures JVM execution;
it does not instrument the resulting native executable.

## Native Image

Import the artifact schema and add a target alongside the JAR and JVM application:

```pkl
import "elide:NativeImage.pkl" as NativeImage

artifacts {
  ["native"] = new NativeImage.NativeImage {
    name = "example"
    from { "classes" }
    options {
      classInit { default = "runtime" }
      linkAtBuildTime { enabled = false }
    }
  }
}
```

```bash
elide build :native
.dev/artifacts/native-image/example
```

The runtime initialization policy lets Micronaut's own metadata identify safe build-time classes. Disabling
blanket build-time linking allows Micronaut's optional integrations to remain absent. Elide includes
`application` and `bootstrap` resources, including environment variants, in JSON, YAML, and properties formats.
The matching Graal processor supplies reflection metadata for annotated application types; Micronaut's libraries
supply their own bean metadata rules. Additional third-party libraries may require their own reachability metadata.
See [Native Image](https://elide.help/docs/toolchain/jvm/native-image) for toolchain selection, flags, and custom metadata.

## Samples

The repository includes complete projects with manifests, Java beans, JUnit tests, JVM distributions, and native targets:

- [Pkl configuration](https://github.com/elide-dev/elide/tree/main/tools/smoketests/micronaut-pkl)
- [Authored JSON resources](https://github.com/elide-dev/elide/tree/main/tools/smoketests/micronaut-resources)

This integration uses Java annotation processing. Kotlin-source processing through KSP is not yet provided; kapt runs
with a [managed or custom toolchain](https://elide.help/docs/toolchain/jvm/kotlinc#choose-a-toolchain). Kotlin can consume beans compiled from Java.
