Skip to content

Commit 689fe74

Browse files
authored
Merge pull request #161 from javaevolved/brunoborges-modern-java-agent-plugin
Add version-aware modern Java agent plugin
2 parents c835c79 + e9419e3 commit 689fe74

14 files changed

Lines changed: 1469 additions & 5 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ site/data/snippets.json
1919

2020
# Generated index page (built from templates/index.html by html-generators/)
2121
site/index.html
22+
site/agent-plugin.html
2223

2324
# Generated locale directories (built by html-generators/ for non-English locales)
2425
site/[a-z][a-z]/

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ This site uses a **JSON/YAML-first** build pipeline:
5050
- **Translations**: `translations/strings/{locale}.yaml` for UI strings, `translations/content/{locale}/` for pattern content (YAML)
5151
- **Deploy**: GitHub Actions runs the generator and deploys to GitHub Pages
5252

53+
### Agent plugin
54+
55+
[`agent-plugins/modern-java-development`](agent-plugins/modern-java-development/)
56+
is a portable Agent Plugins 1.0 package for version-aware Java development. Its
57+
skill detects a project's effective compilation target, then limits guidance to
58+
final language features and APIs available in that Java release.
59+
5360
Generated files (`site/category/*.html`, `site/{locale}/`, and `site/data/snippets.json`) are in `.gitignore` — never edit them directly.
5461

5562
### Internationalization
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Modern Java Development agent plugin
2+
3+
A portable [Agent Plugins 1.0](https://agent-plugins.org/specification) package
4+
for version-aware Java development.
5+
6+
The plugin contributes the `modern-java` skill. The skill detects the project's
7+
effective Java compilation target before recommending language features, APIs,
8+
tooling, or modernization changes. Guidance is cumulative and grouped by the
9+
Java release in which each capability became final.
10+
11+
## Package layout
12+
13+
```text
14+
modern-java-development/
15+
├── plugin.json
16+
└── skills/
17+
└── modern-java/
18+
├── SKILL.md
19+
├── references/
20+
│ ├── core-practices.md
21+
│ └── release-practices.md
22+
└── scripts/
23+
├── detect_java_version.py
24+
└── test_detect_java_version.py
25+
```
26+
27+
## Use
28+
29+
Install or copy this directory into any Agent Plugins-compatible client. When
30+
the skill is active, the agent runs the detector from the Java project root:
31+
32+
```bash
33+
python3 skills/modern-java/scripts/detect_java_version.py .
34+
```
35+
36+
Pass an explicit target when build metadata is unavailable:
37+
38+
```bash
39+
python3 skills/modern-java/scripts/detect_java_version.py . --java-version 21
40+
```
41+
42+
The detector emits JSON so an agent can distinguish the selected target from
43+
lower-confidence runtime evidence and report conflicting build configuration.
44+
45+
## Validate
46+
47+
```bash
48+
python3 -m unittest \
49+
skills/modern-java/scripts/test_detect_java_version.py
50+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3+
"name": "modern-java-development",
4+
"version": "1.0.0",
5+
"description": "Version-aware guidance for writing, reviewing, and modernizing Java projects.",
6+
"author": {
7+
"name": "java.evolved",
8+
"url": "https://javaevolved.github.io"
9+
},
10+
"homepage": "https://javaevolved.github.io",
11+
"repository": "https://github.com/javaevolved/javaevolved.github.io",
12+
"license": "MIT",
13+
"keywords": [
14+
"java",
15+
"modern-java",
16+
"jdk",
17+
"code-review",
18+
"modernization"
19+
]
20+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
name: modern-java
3+
description: Detects a project's effective Java version and provides release-appropriate guidance for writing, reviewing, refactoring, upgrading, and modernizing Java code. Use for Java implementation, architecture, code review, build configuration, migration, performance, concurrency, testing, or API design tasks.
4+
license: MIT
5+
compatibility: Requires Python 3 to run the bundled detector; an agent may inspect the same project files directly when Python is unavailable.
6+
metadata:
7+
author: java.evolved
8+
version: "1.0.0"
9+
---
10+
11+
# Modern Java
12+
13+
Determine the project's effective compilation target before proposing code.
14+
An installed JDK is only fallback evidence; it does not prove which language
15+
features or APIs the build accepts.
16+
17+
## Workflow
18+
19+
1. From the project or module root, run:
20+
21+
```bash
22+
python3 <skill-directory>/scripts/detect_java_version.py .
23+
```
24+
25+
If the user explicitly supplied Java version X, pass
26+
`--java-version X`. Explicit user intent takes precedence over project files.
27+
28+
2. Read the JSON result:
29+
- Use `selected.version` as the target.
30+
- Treat `maven-release`, `gradle-release`, and explicit overrides as stronger
31+
evidence than toolchains, source compatibility, version-manager files, CI,
32+
environment variables, or the installed runtime.
33+
- If `ambiguous` is true, inspect the listed files and determine which module
34+
or build profile is in scope. Do not silently choose the newest version.
35+
- If no version is selected, inspect build and CI configuration. If still
36+
unknown, state the assumption before writing version-sensitive code.
37+
38+
3. Read [core practices](references/core-practices.md), then read the target
39+
release and all earlier applicable groups in
40+
[release practices](references/release-practices.md). Recommendations are
41+
cumulative: Java 21 code may use final features from Java 21 and below.
42+
43+
4. Inspect whether preview is explicitly enabled (`--enable-preview` in both
44+
compile and runtime/test configuration). Do not recommend preview features
45+
by default. Never use a feature finalized after the detected target.
46+
47+
5. Tailor the work:
48+
- **New code:** prefer the clearest final API available at the target.
49+
- **Review:** flag needless legacy patterns only when the replacement is
50+
available at the target and fits the behavior.
51+
- **Modernization:** separate behavior-preserving refactors from Java target
52+
upgrades. Do not raise the target unless requested.
53+
- **Libraries:** respect the published minimum Java version, not the
54+
maintainer's local JDK.
55+
- **Multi-release or multi-module builds:** evaluate each affected source set
56+
or module against its own target.
57+
58+
6. Validate with the project's existing build using its configured toolchain.
59+
Compile and run tests with the same `--release` and preview settings used by
60+
production. Do not treat a successful compile on a newer local JDK as proof
61+
of compatibility.
62+
63+
## Recommendation format
64+
65+
When version matters, briefly name the basis:
66+
67+
> Detected Java 17 from `maven.compiler.release`; recommendations are limited to
68+
> final Java 17 APIs and language features.
69+
70+
For upgrades, distinguish:
71+
72+
- **Usable now:** supported by the current target.
73+
- **Available after upgrade:** requires a specific newer target.
74+
- **Preview:** experimental for a specific release and opt-in only.
75+
76+
Prefer small, behavior-preserving changes. Do not mechanically replace every
77+
older construct: readability, API contracts, allocation behavior, framework
78+
constraints, and team conventions still apply.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Core modern Java practices
2+
3+
Apply these practices at every supported Java version, using only APIs and
4+
syntax available at the detected compilation target.
5+
6+
## Build and compatibility
7+
8+
- Treat `--release`, Maven `maven.compiler.release`, or Gradle
9+
`options.release` as the compatibility contract.
10+
- Pin a reproducible toolchain in the build and CI. Do not rely solely on
11+
`JAVA_HOME` or a developer's installed JDK.
12+
- For libraries, test the minimum supported Java release. Avoid accidentally
13+
linking to APIs from the JDK used to run the build.
14+
- Keep preview features out of production defaults. If adopted deliberately,
15+
enable preview consistently for compilation, tests, execution, packaging,
16+
IDEs, and CI, and plan migration at the next release.
17+
- Prefer supported LTS releases for long-lived production systems unless the
18+
organization intentionally follows the six-month release cadence.
19+
20+
## Language and API design
21+
22+
- Model invalid states out of the type system where practical. Use small value
23+
types, enums, and sealed hierarchies when the target supports them.
24+
- Prefer immutable state and explicit ownership. Make defensive copies at
25+
mutable boundaries; do not expose modifiable internal collections.
26+
- Use `Optional` primarily as a return type for an absent single value, not for
27+
fields, parameters, collections, or serialization contracts by default.
28+
- Use exceptions for exceptional failure, with actionable messages and
29+
preserved causes. Do not catch broad exceptions or silently continue.
30+
- Prefer standard JDK APIs over dependencies when they are equally clear and
31+
capable, but do not rewrite mature library functionality merely to remove a
32+
dependency.
33+
- Keep public APIs unsurprising. Modern syntax is not a reason to break binary,
34+
source, serialization, or framework compatibility.
35+
36+
## Collections, streams, and nullness
37+
38+
- Return empty collections instead of `null`. State mutability and encounter
39+
order in API contracts.
40+
- Use streams for declarative transformations, not for control flow with hidden
41+
side effects. Prefer a loop when it is clearer or permits early exit.
42+
- Do not parallelize streams without measurement and a suitable workload.
43+
- Establish an explicit nullness policy. Prefer JSpecify annotations when the
44+
surrounding ecosystem and tooling support them.
45+
46+
## Concurrency
47+
48+
- Prefer structured ownership of tasks and resources. Always define
49+
cancellation, timeout, interruption, and failure propagation behavior.
50+
- Preserve interruption (`Thread.currentThread().interrupt()`) when an
51+
`InterruptedException` cannot be propagated.
52+
- Use concurrent collections and high-level synchronization utilities before
53+
hand-written locking. Document invariants protected by locks.
54+
- Measure before selecting executors, pool sizes, lock-free structures, or
55+
virtual-thread migration. CPU-bound and I/O-bound workloads need different
56+
strategies.
57+
58+
## Security and reliability
59+
60+
- Validate untrusted input at boundaries. Avoid native Java serialization for
61+
untrusted data; apply deserialization filters where legacy use remains.
62+
- Use modern TLS defaults, authenticated encryption, `SecureRandom`, and
63+
purpose-built password/key derivation APIs. Never invent cryptography.
64+
- Use try-with-resources for every `AutoCloseable` whose lifetime is locally
65+
owned.
66+
- Add timeouts to network calls and bounded behavior to queues, retries,
67+
payloads, and caches.
68+
69+
## Performance and observability
70+
71+
- Measure with JFR, JDK tools, and a representative workload before optimizing.
72+
- Use JMH for microbenchmarks; include warmup, forks, and consumed results.
73+
- Prefer simple allocation-friendly code, but do not trade correctness or
74+
clarity for speculative micro-optimizations.
75+
- Include enough context in logs to diagnose failures without exposing secrets
76+
or personal data.
77+
78+
## Testing
79+
80+
- Test externally visible behavior and edge cases, not implementation details.
81+
- Use the project's existing test framework and build. Keep tests deterministic;
82+
control clocks, randomness, concurrency, locale, timezone, and filesystem
83+
dependencies where relevant.
84+
- Add focused regression tests for bug fixes and compatibility tests for public
85+
APIs or serialized formats.

0 commit comments

Comments
 (0)