Synthèse automatique
Guide une procédure systématique pour diagnostiquer et corriger un test Morphia en échec, en inspectant le code source, le bytecode généré et les chemins AOT/runtime de Critter.
Points forts
- Workflow en six étapes, de l'exécution ciblée du test à la vérification après correction.
- Commandes Maven précises, avec les options pour éviter dokka et les filtres de tests mal appliqués.
- Explique comment relier l'erreur aux générateurs de bytecode Critter et distinguer les chemins AOT et runtime.
- Donne des techniques d'inspection concrètes : javap, sources générées et jars dans ~/.m2.
Limites
- Très spécifique au projet Morphia et à son architecture Critter ; peu réutilisable tel quel ailleurs.
- Suppose une bonne connaissance de Java, de Maven et du bytecode pour interpréter les traces.
- Les outils autorisés sont limités à mvnw, javap, unzip et grep ; la correction de fichiers peut nécessiter des outils hors skill.
À utiliser lorsqu'un test Morphia échoue et que la cause probable se situe dans le code généré ou dans le chemin AOT/runtime de Critter.
À éviter pour diagnostiquer un échec de test dans un autre projet Java ou pour des problèmes sans rapport avec la génération de bytecode Morphia.
Analyse de sécurité
PrudenceThe 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.
Exemples
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.
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
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. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Outils déclarés par l’auteur (à vérifier dans votre agent) : Bash(./mvnw:*), Bash(javap:*), Bash(unzip:*), Bash(grep:*)
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.
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 doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.
Installation officielle d’OpenSkillsopenskills install './.skill-downloads/diagnose-test-failures-mvda86uq'openskills read 'diagnose-test-failures-mvda86uq'La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.
Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.
openskills syncMode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/diagnose-test-failures-mvda86uq/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Comparaison de performances ClickHouse
Testing
Évaluez les résultats de tests de performance ClickHouse, analysez les régressions de PR, comparez avec l'historique et vérifiez la fiabilité des mesures.
Analyse des rapports de performance CI
Testing
Analyse les rapports de comparaison de performance CI pour une PR ClickHouse. Recoupe l'historique master pour distinguer les vraies régressions des tests instables.
Méthode Santa
Testing
Vérification adversarial multi-agents avec deux réviseurs indépendants. La sortie est vérifiée deux fois et corrigée itérativement jusqu'à ce que les deux acceptent avant publication.