Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Java Reflection And Method Handles

ASecurity

Runtime access to code through dynamic names: what reflection costs beyond speed — weaker ordinary compile-time/refactoring checks, module access requirements, and closed-world native-image constraints — the alternatives that keep the checking (interfaces, ServiceLoader, annotation processing, code generation), MethodHandles and VarHandles for genuinely dynamic access, and the security boundary around resolving a name that came from outside. Use when reflection appears in application code, wh...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentrustgojavadebuggingrefactoringapisecurityperformance

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill java-reflection-and-method-handles --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Java Reflection And Method Handles?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Java Reflection And Method Handles
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-java-reflection-and-method-handles/badge)](https://www.skillsdirectory.com/skills/robsonkades-java-reflection-and-method-handles)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: java-reflection-and-method-handles
description: >
  Runtime access to code through dynamic names: what reflection costs beyond speed — weaker
  ordinary compile-time/refactoring checks, module access requirements,
  and closed-world native-image constraints — the
  alternatives that keep the checking (interfaces, ServiceLoader, annotation processing,
  code generation), MethodHandles and VarHandles for genuinely dynamic access, and the
  security boundary around resolving a name that came from outside. Use when reflection
  appears in application code, when setAccessible needs --add-opens, when a framework works
  on the JVM and fails under native image, when a class name arrives from configuration or a
  payload, when Method.invoke or invokeWithArguments sits on a hot path, or when a runbook
  still sets sun.reflect.inflationThreshold or noInflation. FFM and JNI mechanics are
  jni-and-ffm, the annotations reflection reads are java-annotations, and deserialisation
  attack surface is java-serialization-hardening.
---

# Java Reflection and Method Handles

## Purpose

Keep dynamic access deliberate, narrow and described by metadata/contracts. Compilers and basic
refactoring tools cannot prove a string-computed edge; specialized analyzers may approximate it,
but correctness still depends on runtime inputs, loader/module identity and configuration.
Two failure modes: application code using reflection where an interface would do, so a rename
compiles and fails at runtime; and reflection over a name that came from outside the process,
which becomes an execution primitive once initialization, construction or invocation is reachable.

## Workflow

0. **Inspect the target and ownership contract.** Read compiler release/toolchains, actual
   JDK/vendor, module descriptors, launch flags, loader boundaries and native-image/tool
   versions. The Java snippets fit Java 17 unless stated: method handles need Java 7+,
   VarHandles/JPMS/privateLookupIn Java 9+, sealed types Java 17+ and non-preview pattern
   switches Java 21+. Preserve the project target; do not enable preview, upgrade or open
   modules implicitly. Missing launch/loader evidence makes an access diagnosis conditional.
1. **Ask what varies.** If the set of implementations is known at build time, an interface, a
   sealed hierarchy or map of suppliers often suffices. `ServiceLoader` keeps invocation
   typed but provider discovery/instantiation can still fail at runtime. Dynamic access can
   be appropriate for plugins, frameworks and tooling; inspect the actual variability.
2. **If it must be dynamic, decide where the openness stops.** One factory, one registry, one
   adapter — never scattered `getDeclaredMethod` calls through business code.
3. **Validate tokens before resolution.** Map external tokens to code-owned types/operations.
   `asSubclass` narrows a genuinely configurable class to an expected supertype, but does not
   authorize its constructor, static initializer, loader, code source or later methods.
4. **Choose the mechanism by frequency.** A one-off at startup: `Class`/`Method` reflection is
   fine—but resolve/validate once and cache with a lifecycle-safe key. Repeated on a measured hot
   path: compare a stable typed `MethodHandle`, a bound functional adapter and generated code.
5. **Register what the runtime cannot see** — module `opens`, native-image reflection
   configuration, AOT metadata — and test on the target runtime, because a JVM run proves
   nothing about a native image.

## Rules

- Prefer an interface to reflection. The common shape — "instantiate the class named in
  configuration, then call it through an interface" — needs reflection only for the
  construction; every call afterwards goes through the interface, checked by the compiler.
- Prefer `ServiceLoader` to hand-rolled classpath scanning for plugin discovery: it is
  declarative (`META-INF/services` or `provides … with` in a module), the JDK's own mechanism,
  and visible to the module system. It does not provide a general priority order, dependency
  injection, failure isolation or unload lifecycle, and native-image support must still be
  verified for the toolchain.
- Prefer build-time generation when the needed inputs are available then, it preserves the
  supported discovery/reload contract, and its build/debugging cost is justified. Post-build
  providers or runtime schemas may need dynamic discovery with a typed boundary. Keep adequate
  existing startup reflection; generated source improves visibility but does not by itself prove
  equivalent behavior or lower cost — see java-annotations.
- Reflection loses more than performance: no ordinary compile-time type checking, incomplete
  rename/find-usage/dead-code results unless specialized tooling understands the metadata, and
  less direct stack traces. Those costs apply even when invocation happens once at startup.
- `setAccessible(true)` on another module's private member fails under strong encapsulation
  unless the package is opened (`opens`, `--add-opens`). Requiring `--add-opens` in production
  is a design decision, not a workaround — record it and revisit it, because the JDK's direction
  is towards restricting it further. Reflecting into JDK internals is not a supported contract.
- Never let a payload, header or message field directly select a class/member. `Class.forName`
  with initialization can execute static initialization; construction/invocation and polymorphic
  deserialization can reach powerful gadget behavior. Map known tokens to known operations and
  validate code source/loader where plugins are allowed; a deny-list is not a security boundary—
  java-serialization-hardening covers the deserialisation side.
- Wrap reflective failures at the boundary. `NoSuchMethodException`, `IllegalAccessException`
  and `InvocationTargetException` are implementation detail; propagate a domain or configuration
  error, and always unwrap `InvocationTargetException.getCause()` — losing the cause hides the
  real exception under a generic wrapper (java-exception-design).
- For repeated dynamic invocation, resolve a typed `MethodHandle` (or `VarHandle`) once. A stable
  handle visible as a compiler constant often enables adapter/target inlining, but this is a JIT
  decision, not a `static final` guarantee. `invokeWithArguments` intentionally performs generic
  array/spreader adaptation; `Method.invoke` has varargs/boxing/wrapping/access costs. Measure the
  actual target and storage shape. Core reflection is MethodHandle/VarHandle-based since JDK 18;
  the old implementation was removed in JDK 22, making old inflation/direct-handle switches no-ops.
- Use `VarHandle` rather than `sun.misc.Unsafe` or reflection for low-level field access with
  explicit memory-ordering semantics. Query `isAccessModeSupported`; final fields support reads,
  not arbitrary writes. `varhandles-and-memory-ordering` covers the access modes.
- Avoid reflection that bypasses a supported API or object invariant. Private access couples
  callers to representation; in tests, prefer the real API or an explicit seam. Bounded legacy
  characterization/tooling can justify reflection when compatibility prevents a better seam;
  retain its access/lifecycle contract, with retirement or review conditions for temporary or
  unsupported seams — java-test-design.
- Native interop is a different boundary: foreign code can crash or corrupt the process,
  although Java-side checks may throw. FFM became final in Java 22; API support and native-access
  configuration depend on the target release. It is not a replacement for ordinary reflection;
  hand native interop decisions to jni-and-ffm and off-heap-memory.
- Closed-world native-image analysis may infer constant reflective edges and framework metadata,
  but runtime-computed access needs owned reachability metadata. Missing edges may fail at build
  time or only on an untrained runtime path. Test the native artifact itself; this constraint can
  justify build-time alternatives—see `graalvm-native-image`.
- Treat `Lookup`, `MethodHandle` and `VarHandle` as capabilities. Access checks happen when a
  handle is created; code receiving the handle can invoke it without re-proving the creator's
  private access. Never expose a full-power lookup or non-public handle across an untrusted plugin
  boundary; expose a narrow parent-owned interface instead.
- Cache without pinning reloadable code. A `Class`, reflected member, method handle, lambda/proxy
  class or cache value can retain its defining loader. Parent-loaded framework caches should use
  lifecycle eviction, `ClassValue` where appropriate, or rigorously tested weak-key designs.

## Acceptance gate

- Resolve mandatory members/providers during their owner's startup and optional plugins during
  their own lifecycle; report missing/ambiguous signatures with loader/module/code source.
- Test the deployment modes actually supported: named/classpath modules, duplicate loaders,
  reload/unload and native artifacts where applicable. Do not build unused modes merely to
  satisfy this list.
- Exercise primitive/reference/null/varargs signatures and verify `WrongMethodTypeException`,
  target exceptions and access failures are translated without losing causes.
- Benchmark only after proving the reflective path is material; include direct/interface,
  `Method.invoke`, stable/unstable handles and generated alternatives with allocation profiling.

Deliver the dynamic boundary, allowed operations, exact signature/access requirements, lifecycle
and failure mapping, plus checks actually run. Separate structural/access correctness from
unmeasured speed and untested native-image/reload claims.

## References

- [When reflection is justified, and what to use instead](references/when-reflection-is-justified.md)
  — read when deciding whether a requirement genuinely needs reflection, when replacing
  reflective code with an interface, `ServiceLoader` or generated code, or when reviewing
  reflection found in application code.
- [Method handles, VarHandles and module encapsulation](references/method-handles-and-encapsulation.md)
  — read when dynamic access is unavoidable: choosing between `Method`, `MethodHandle` and
  generated accessors, resolving handles correctly, and dealing with `opens`, `--add-opens` and
  native-image configuration.
- [What reflection and handles cost on the current runtime](references/reflection-cost-model.md)
  — JEP 416's method-handle implementation of core reflection, the per-operation cost table
  from `Class.forName` to `invokeWithArguments`, and how to verify inlining and boxing rather
  than assume them; read when a hot path invokes reflectively, when a runbook still tunes the
  `sun.reflect.*` inflation flags, or when choosing between `Method.invoke`, `invoke`,
  `invokeExact` and `invokeWithArguments`.

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →