Implement and review Java code changes for Micronaut framework repositories using maintainer standards, including JSpecify null-safety conventions. Use when users ask to add or refactor Java code, fix framework bugs, evolve internal APIs, or prepare committer-ready changes with tests and verification.
2) Implement Java with Micronaut maintainer conventions
Prefer modern Java idioms where they improve clarity (records, sealed types, pattern matching, var for local inference), but only when supported by the repository toolchain/target level.
Do not use fully qualified class names unless import conflicts force it.
Micronaut Java code uses JSpecify nullness annotations from org.jspecify.annotations; use JSpecify for new or modified nullability contracts.
New Java packages must include package-info.java with @NullMarked and import org.jspecify.annotations.NullMarked; when touching an existing package without @NullMarked, add it unless the local code has an explicit exception.
Use org.jspecify.annotations.Nullable for nullable values, including nullable parameters, return values, fields, array/component positions such as String @Nullable [], nullable collection elements such as List<@Nullable T>, and nullable type bounds such as <T extends @Nullable Object>.
Preserve existing nullability intent when editing older code. Use JSpecify for new or modified contracts, but do not rewrite deliberate compatibility annotations such as io.micronaut.core.annotation.Nullable or jakarta.annotation.Nullable unless the task is specifically a nullability migration and compatibility impact has been checked.
Prefer constructor injection and immutable state over field injection.
For configuration models, prefer @ConfigurationProperties over scattered @Value usage.
3) Enforce API boundaries and compatibility
Treat all public-facing changes through a Semantic Versioning lens (https://semver.org/) before implementation.
Classify impact explicitly: patch for backward-compatible fixes, minor for backward-compatible feature additions, major for breaking API/behavioral changes.
Keep public API binary compatible unless a major-version change explicitly allows breaks.
Prefer non-breaking API evolution first: deprecate existing methods and add replacement variants/overloads instead of deleting methods or changing signatures in place.
When using the deprecate-and-add path, keep deprecated APIs functional, point to replacements in Javadoc, and schedule removals only for the next major version.
If breaking public-facing changes are explicitly allowed, document them in the user guide under src/main/docs/guide with migration notes, and update toc.yml when adding new guide sections.
Mark non-user-facing APIs with @io.micronaut.core.annotation.Internal.
Mark unstable public APIs with @io.micronaut.core.annotation.Experimental and avoid presenting them as stable contracts.
Mark members directly called by generated code with @io.micronaut.core.annotation.UsedByGeneratedCode; preserve those signatures unless the generated-code callers are updated in the same change.
Keep visibility as narrow as possible for non-public internals.
When deprecating API, provide migration-friendly Javadoc and avoid silent behavioral breaks.
4) Keep Gradle/build changes convention-aligned
Use ./gradlew for all Gradle execution.
Use Gradle version catalogs (gradle/libs.versions.toml) instead of hard-coded dependency versions.
Use appropriate scopes (api, implementation, compileOnly, runtimeOnly) based on API exposure.
Do not add custom build logic directly in module build files when it belongs in convention plugins.
When uncertain about module paths, use ./gradlew projects and prefer canonical micronaut-* project names.
5) Verify before completion
First confirm canonical verification tasks from CONTRIBUTING.md and existing CI/build files, then run the repository equivalents from root.
Common sequence in Micronaut repositories:
./gradlew :<module>:compileTestJava
# If module includes Groovy tests:
./gradlew :<module>:compileTestGroovy
./gradlew :<module>:test --tests 'pkg.ClassTest'
./gradlew :<module>:test
# If repository documents cM alias/checkstyle aggregate task:
./gradlew -q cM
./gradlew -q spotlessCheck
./gradlew check
./gradlew docs
For API-affecting changes, also run if configured in the repository:
./gradlew japiCmp
If Spotless fails, run ./gradlew -q spotlessApply and re-run spotlessCheck.
Guardrails
Do not introduce javax.inject usage.
Do not introduce legacy or third-party nullability annotations for new or modified Micronaut Java contracts when JSpecify is available, except for deliberate compatibility annotations whose impact has been checked.
Do not hard-code dependency versions in module build files.
Do not break public APIs without explicit major-version intent.
Do not skip tests or docs verification for code changes.
Do not use reflection as a convenience in framework internals.
Delivery Contract
When finishing implementation work, report:
Exactly which files changed and why.
Whether the change is API-facing or internal-only.
Semantic Versioning impact classification (patch/minor/major) for any public-facing change.
For deprecate-and-add API evolution, which elements were deprecated and which replacement variants were introduced.
For breaking public-facing changes, which user guide files were updated and what migration guidance was added.
Commands executed for verification and outcomes.
Any follow-up risk (for example compatibility implications).
Validation Checklist
SKILL.md frontmatter is valid and name matches directory (coding).
Guidance is maintainer-focused (not end-user app guidance).
Java conventions include JSpecify nullability (@NullMarked, @Nullable), DI, and reflection-free guidance.
API boundary guidance includes @Internal, @Experimental, @UsedByGeneratedCode, and compatibility checks.
For public API evolution without breaking changes, deprecations include clear replacement guidance and functional compatibility is preserved.
If breaking changes are allowed, user guide docs in src/main/docs/guide are updated with migration notes.
Verification includes tests, style checks, check, and docs.
1---2name: coding-43description: Implement and review Java code changes for Micronaut framework repositories using maintainer standards, including JSpecify null-safety conventions. Use when users ask to add or refactor Java code, fix framework bugs, evolve internal APIs, or prepare committer-ready changes with tests and verification.4license: Apache-2.05---67# Coding (Micronaut Committer)89Use this skill for maintainer-facing Java implementation work in Micronaut repositories. Do not default to end-user application shortcuts.1011## Goal1213Deliver minimal, source-backed Java changes that preserve framework quality: binary compatibility, JSpecify null-safety, reflection-free behavior, and full Gradle verification (`check`, `docs`, and compatibility checks when API-facing).1415## Trigger Examples1617Should trigger:1819- "Implement this Micronaut Java feature in `src/main/java` and keep API compatibility."20- "Refactor this module internals and mark non-public APIs correctly."21- "Fix failing framework tests and prepare committer-ready validation output."22- "Add configuration support using Micronaut conventions, not app-level shortcuts."2324Should not trigger:2526- "Explain Micronaut basics to a beginner."27- "Create an end-user sample app from scratch."28- "Only edit release notes/changelog text."2930## Procedure31321. Establish scope and API impact.332. Implement Java code with Micronaut maintainer conventions.343. Enforce API boundaries and binary compatibility.354. Keep Gradle/build changes aligned with repository conventions.365. Verify with maintainer-grade checks before completion.3738### 1) Establish scope and API impact3940- Identify affected modules and whether any change is public API or internal-only.41- Inspect existing package patterns before editing (imports, nullability style, tests, naming).42- For API-facing edits, plan compatibility checks up front (`japiCmp`).43- Keep change surface minimal; avoid opportunistic refactors unless required.4445### 2) Implement Java with Micronaut maintainer conventions4647- Prefer modern Java idioms where they improve clarity (records, sealed types, pattern matching, `var` for local inference), but only when supported by the repository toolchain/target level.48- Do not use fully qualified class names unless import conflicts force it.49- Micronaut Java code uses JSpecify nullness annotations from `org.jspecify.annotations`; use JSpecify for new or modified nullability contracts.50- New Java packages must include `package-info.java` with `@NullMarked` and `import org.jspecify.annotations.NullMarked`; when touching an existing package without `@NullMarked`, add it unless the local code has an explicit exception.51- Use `org.jspecify.annotations.Nullable` for nullable values, including nullable parameters, return values, fields, array/component positions such as `String @Nullable []`, nullable collection elements such as `List<@Nullable T>`, and nullable type bounds such as `<T extends @Nullable Object>`.52- Preserve existing nullability intent when editing older code. Use JSpecify for new or modified contracts, but do not rewrite deliberate compatibility annotations such as `io.micronaut.core.annotation.Nullable` or `jakarta.annotation.Nullable` unless the task is specifically a nullability migration and compatibility impact has been checked.53- Avoid reflection-oriented implementations in framework code paths; prefer Micronaut compile-time/introspection mechanisms.54- Use `jakarta.inject` APIs for DI, not `javax.inject`.55- Prefer constructor injection and immutable state over field injection.56- For configuration models, prefer `@ConfigurationProperties` over scattered `@Value` usage.5758### 3) Enforce API boundaries and compatibility5960- Treat all public-facing changes through a Semantic Versioning lens (`https://semver.org/`) before implementation.61- Classify impact explicitly: patch for backward-compatible fixes, minor for backward-compatible feature additions, major for breaking API/behavioral changes.62- Keep public API binary compatible unless a major-version change explicitly allows breaks.63- Prefer non-breaking API evolution first: deprecate existing methods and add replacement variants/overloads instead of deleting methods or changing signatures in place.64- When using the deprecate-and-add path, keep deprecated APIs functional, point to replacements in Javadoc, and schedule removals only for the next major version.65- If breaking public-facing changes are explicitly allowed, document them in the user guide under `src/main/docs/guide` with migration notes, and update `toc.yml` when adding new guide sections.66- Mark non-user-facing APIs with `@io.micronaut.core.annotation.Internal`.67- Mark unstable public APIs with `@io.micronaut.core.annotation.Experimental` and avoid presenting them as stable contracts.68- Mark members directly called by generated code with `@io.micronaut.core.annotation.UsedByGeneratedCode`; preserve those signatures unless the generated-code callers are updated in the same change.69- Keep visibility as narrow as possible for non-public internals.70- When deprecating API, provide migration-friendly Javadoc and avoid silent behavioral breaks.7172### 4) Keep Gradle/build changes convention-aligned7374- Use `./gradlew` for all Gradle execution.75- Use Gradle version catalogs (`gradle/libs.versions.toml`) instead of hard-coded dependency versions.76- Use appropriate scopes (`api`, `implementation`, `compileOnly`, `runtimeOnly`) based on API exposure.77- Do not add custom build logic directly in module build files when it belongs in convention plugins.78- When uncertain about module paths, use `./gradlew projects` and prefer canonical `micronaut-*` project names.7980### 5) Verify before completion8182First confirm canonical verification tasks from `CONTRIBUTING.md` and existing CI/build files, then run the repository equivalents from root.8384Common sequence in Micronaut repositories:8586```bash87./gradlew :<module>:compileTestJava88# If module includes Groovy tests:89./gradlew :<module>:compileTestGroovy90./gradlew :<module>:test --tests 'pkg.ClassTest'91./gradlew :<module>:test92# If repository documents cM alias/checkstyle aggregate task:93./gradlew -q cM94./gradlew -q spotlessCheck95./gradlew check96./gradlew docs97```9899For API-affecting changes, also run if configured in the repository:100101```bash102./gradlew japiCmp103```104105If Spotless fails, run `./gradlew -q spotlessApply` and re-run `spotlessCheck`.106107## Guardrails108109- Do not introduce `javax.inject` usage.110- Do not introduce legacy or third-party nullability annotations for new or modified Micronaut Java contracts when JSpecify is available, except for deliberate compatibility annotations whose impact has been checked.111- Do not hard-code dependency versions in module build files.112- Do not break public APIs without explicit major-version intent.113- Do not skip tests or docs verification for code changes.114- Do not use reflection as a convenience in framework internals.115116## Delivery Contract117118When finishing implementation work, report:1191201. Exactly which files changed and why.1212. Whether the change is API-facing or internal-only.1223. Semantic Versioning impact classification (patch/minor/major) for any public-facing change.1234. For deprecate-and-add API evolution, which elements were deprecated and which replacement variants were introduced.1245. For breaking public-facing changes, which user guide files were updated and what migration guidance was added.1256. Commands executed for verification and outcomes.1267. Any follow-up risk (for example compatibility implications).127128## Validation Checklist129130- [ ] `SKILL.md` frontmatter is valid and `name` matches directory (`coding`).131- [ ] Guidance is maintainer-focused (not end-user app guidance).132- [ ] Java conventions include JSpecify nullability (`@NullMarked`, `@Nullable`), DI, and reflection-free guidance.133- [ ] API boundary guidance includes `@Internal`, `@Experimental`, `@UsedByGeneratedCode`, and compatibility checks.134- [ ] For public API evolution without breaking changes, deprecations include clear replacement guidance and functional compatibility is preserved.135- [ ] If breaking changes are allowed, user guide docs in `src/main/docs/guide` are updated with migration notes.136- [ ] Verification includes tests, style checks, `check`, and `docs`.137138## References139140- `CONTRIBUTING.md`141- `MAINTAINING.md`142- `.agents/skills/gradle/SKILL.md`143- `.agents/skills/docs/SKILL.md`144- `.agents/skills/skill-creator/references/spec-checklist.md`
Run npx skillmds@latest add micronaut-projects/coding-4 in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Implement and review Java code changes for Micronaut framework repositories using maintainer standards, including JSpecify null-safety conventions. Use when users ask to add or refactor Java code, fix framework bugs, evolve internal APIs, or prepare committer-ready changes with tests and verification. It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: CAUTION, Skill Scanner: PASS. Capability flags: makes network calls. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under Apache-2.
micronaut-projects (@micronaut-projects) published this skill. Their other Agent Skills are listed on their SkillMD profile.