Automated summary
Provides a systematic procedure for diagnosing and fixing a failing Morphia test by inspecting source code, generated bytecode, and Critter's AOT/runtime paths.
Strengths
- Six-step workflow from targeted test execution through post-fix verification.
- Precise Maven commands with flags to skip dokka and avoid misapplied test filters.
- Explains how to connect failures to Critter bytecode generators and distinguish AOT from runtime paths.
- Includes concrete inspection techniques: javap, generated sources, and source jars in ~/.m2.
Limitations
- Highly specific to the Morphia project and its Critter architecture; not directly reusable elsewhere.
- Assumes solid knowledge of Java, Maven, and bytecode to interpret stack traces.
- Allowed tools are limited to mvnw, javap, unzip, and grep; fixing files may require tools outside the skill.
Use when a Morphia test fails and the likely cause lies in generated code or Critter's AOT/runtime path.
Avoid for diagnosing test failures in other Java projects or issues unrelated to Morphia bytecode generation.
Security analysis
CautionThe skill is a narrowly scoped debugging workflow for the Morphia project. All four declared tools are used for legitimate, read-mostly purposes: running tests/builds, decompiling with `javap`, inspecting jars with `unzip -p`, and searching with `grep`. There are no destructive commands (no `rm -rf`, no force pushes), no network exfiltration, no obfuscated/base64 payloads, no attempts to disable safety controls, and no instruction-override attempts in the content. The only reason it is not 'safe' is that it drives real Maven builds, which compile and execute arbitrary project/plugin code under the user's account — standard for a build-focused skill, but a genuine execution surface.
- •Runs Maven build lifecycle (`./mvnw test`, `./mvnw install`), which executes build plugins and project code with the agent's privileges
- •Invokes `unzip -p` against jars in `~/.m2/repository/`, i.e. reads local artifact files (read-only, no exfiltration)
- •Bash(./mvnw:*) is a wildcard grant over the Maven wrapper, which executes project build plugins and can download/run arbitrary code from the local project and remote repositories (network access implied).
- •Instructions direct decompiling/inspecting classes under ~/.m2/repository with unzip -p (read-only, but touches the shared local repository and can surface jar contents).
- •No destructive, obfuscated, or exfiltrating instructions were found; the skill text contains no prompt-injection or role-manipulation attempts.
Examples
A test in morphia-core is failing with a NoSuchMethodError on a generated __read accessor. Run the failing test with Maven, inspect the generated classes in target/test-classes, determine whether the AOT or runtime Critter path produced the bad accessor, fix it minimally, and re-run the test.Diagnose this Morphia test failure: the runtime Critter path throws an IllegalAccessError from a hidden nestmate accessor. Trace the responsible generator, compare it with a working generator for the same pattern, apply a minimal fix, and verify the test class.The failing Morphia test depends on a recently changed module. Rebuild the necessary modules without tests and with deploy/invoker skips, run the single failing test, trace the root cause through source and generated bytecode, then verify the fix.name: diagnose description: Use when a test fails and you need to diagnose the root cause. Run the test, read errors, trace through generated and source code, fix, and verify. allowed-tools: Bash(./mvnw:), Bash(javap:), Bash(unzip:), Bash(grep:)
Diagnose Test Failure
Overview
Systematic diagnosis of test failures in the Morphia project. Run the test, read the full error, trace the root cause through source and generated code, fix minimally, and verify.
Workflow
-
Run the failing test
./mvnw test -pl :module-name -Dtest="ClassName#methodName" -Ddeploy.skip=true- Use
-Ddeploy.skip=trueto skip dokka - Do NOT use
-amwith-Dtest=(applies test filter to all modules) - If dependencies need rebuilding first:
./mvnw install -pl :dep1,:dep2 -DskipTests -Ddeploy.skip=true -Dinvoker.skip=true
- Use
-
Read the full error - stack trace, error message, line numbers. Don't skip anything.
-
Find relevant code - Read both source AND generated code:
- Source:
src/main/,src/test/ - Generated bytecode:
target/test-classes/- usejavap -c -p ClassNameto decompile - Generated sources:
target/generated-sources/ - Interfaces from dependencies: check
~/.m2/repository/source jars withunzip -p
- Source:
-
Trace the root cause - Follow the error backward:
- What method is missing/wrong?
- What generated it? All critter bytecode comes from the Class-File API generators in
core/src/main/java/dev/morphia/critter/parser/generator/(see "Critter Code Generation" below). - Was it the AOT path (critter-maven, woven
__read*/__write*methods) or the runtime path (hidden nestmate accessors)? - What does the interface/superclass require?
- Compare with a working generator for the same pattern (e.g. how
PropertyAccessorGeneratorboxes primitives)
-
Fix minimally - One change at a time. Rebuild affected modules:
./mvnw install -pl :morphia-core,:critter-maven -DskipTests -Ddeploy.skip=true -Dinvoker.skip=true -
Verify - Re-run the failing test AND related tests in the same class.
Critter Code Generation
Critter generates bytecode with the Class-File API (java.lang.classfile), using the
jdk-classfile-backport library (package io.smallrye.classfile) so it runs on Java 17.
There is no Gizmo or ASM in the generators. Everything is in
core/src/main/java/dev/morphia/critter/parser/generator/, and CritterGenerator is the entry point.
| Generator | Produces |
|-----------|----------|
| AddFieldAccessorMethods / AddMethodAccessorMethods | AOT only: rewrites the entity class to add synthetic __readXxx/__writeXxx methods |
| PropertyAccessorGenerator | AOT only: a PropertyAccessor that calls the woven __read*/__write* methods |
| NestmateAccessorGenerator | Runtime only: a PropertyAccessor using direct getfield/putfield/invokevirtual, defined as a hidden nestmate (Lookup.defineHiddenClass(..., NESTMATE)) and registered in NestmateAccessorRegistry |
| PropertyModelGenerator | A CritterPropertyModel per property |
| EntityModelGenerator | The CritterEntityModel for the entity |
| VarHandleAccessorGenerator | A VarHandle/MethodHandle-based accessor; not used by the main pipeline right now (only TestVarHandleAccessor) |
The two paths:
- AOT:
critter-maven(generate-models/generate-test-models) callsCritterGenerator.generate(type, loader, false). It writes the generated models and the woven entity classes to disk under__morphia/<entity>/. - Runtime: when no pre-generated model is on the classpath,
CritterMappercallsgenerate(type, loader, true). That defines classes in aCritterClassLoaderplus hidden nestmates. If it fails, it logs once and falls back to a reflectiveEntityModel. Hidden nestmates need full privilege access, so an entity outside Morphia's module (on the classpath: loaded by a different class loader) fails with aNestmateAccessException;CritterMapperlogs a specific "can't access ... isn't in Morphia's module" warning for it. That's expected for those layouts, and the fix is critter-maven AOT models, not a generator change.
PropertyFinder rejects some entities for AOT with UnsupportedOperationException("AOT skip: ..."):
inherited fields the entity can't reach and whose declaring class can't be rewritten (e.g. a private field in a library
superclass), fields shadowing a superclass field, array-typed fields, and entities whose @Id is on a getter.
Entities with no @Id at all (e.g., embedded types) are generated normally. A final field's __writeXxx sets it through
a cached java.lang.reflect.Field, since putfield may only write a final field from a constructor. An inherited field from a superclass in the
same output directory or jar gets its __readXxx/__writeXxx methods woven into that superclass, which the entity
inherits. The rejected entities use runtime generation instead, so an "AOT skip" warning in the critter-maven output is
expected for them and is not an error.
Common Morphia/Critter Issues
| Error | Likely Cause |
|-------|-------------|
| AbstractMethodError | A generated class is missing an interface method. Generators emit methods with explicit erased descriptors (e.g. get(Ljava/lang/Object;)Ljava/lang/Object;), and nothing adds bridge methods for you |
| VerifyError / Bad type on operand stack | Usually a primitive/reference mismatch: a primitive was used where an Object was expected, or the reverse, without boxing or unboxing |
| ClassCastException in a generated accessor | checkcast to the wrong owner (for an inherited field, the declaring class vs the entity class) or to the wrong wrapper type |
| IllegalAccessError from a nestmate accessor | The hidden class was defined against the wrong lookup class. It must be privateLookupIn the field's declaring class |
| NoSuchMethodError __read*/__write* | The AOT accessor ran against an unwoven entity class, e.g. the woven class from generated-classes/critter is not ahead of the original on the classpath |
| ClassNotFoundException __morphia.* | Critter code generation didn't run or class not registered |
Key Gotchas
- The Class-File API is low-level: no automatic boxing, casting, or bridge methods. Emit each step explicitly.
- Boxing:
invokestatic Wrapper.valueOf(prim)Wrapper. Unboxing:checkcast Wrapper, theninvokevirtual Wrapper.xxxValue(). Helpers live inGenerationUtils(PRIMITIVE_TO_WRAPPER,primitiveUnboxMethod,primitiveClassDesc). checkcastonly accepts reference types. To get a primitive from anObject, cast to the wrapper and then unbox.- Keep non-public types out of generated descriptors. AOT accessors use
Objectin__read*/__write*signatures for reference types, and the cast happens inside the entity. - Inspect generated classes with
javap -c -p. AOT output is undertarget/generated-classes/critter(main) ortarget/test-classes/**/__morphia/(tests). Runtime-generated classes are in memory only.
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/diagnose-test-failures-mvda86uq' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/diagnose-test-failures-mvda86uq/download' --output '.skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md.part' && mv '.skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md.part' '.skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Tools declared by the author (check availability in your agent): Bash(./mvnw:*), Bash(javap:*), Bash(unzip:*), Bash(grep:*)
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md' && test -s '.skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/diagnose' && cp -R '.skill-downloads/diagnose-test-failures-mvda86uq' '.claude/skills/diagnose'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/diagnose-test-failures-mvda86uq'openskills read 'diagnose-test-failures-mvda86uq'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
ClickHouse Performance Comparison
Testing
Evaluate ClickHouse performance test results, check PR performance changes, compare with history, and assess whether a result is actionable.
Analyze CI Performance Reports
Testing
Analyze CI performance comparison reports for a ClickHouse PR. Cross-references master history to distinguish real regressions from flaky tests.
Santa Method
Testing
Multi-agent adversarial verification with two independent reviewers. Output is checked twice and iteratively fixed until both pass before shipping.