Troubleshooting and checklist
First: do the rules run
./gradlew elcore3 -PlistRules
If the first line shows the ruleset ([rules] petstore: hexagonal-springboot + … + com.example.rules.PetstoreRules)
and our rule ids appear under the intended target, it is connected. If they do not appear, it is a
connection problem; if they appear but there is no result, it is a target or file-ownership problem.
By symptom
| Symptom | Cause | Fix |
|---|---|---|
Rule set class '…' is not on the generator's classpath | a typo in the class name in rules, or a missing elasticore project(':ps-rules') (coordinates, for a jar) | check the name and the dependency |
NoSuchMethodError, AbstractMethodError during generation | the rules module's elasticore-base version differs from the plugin version | make the two versions the same (Your first ruleset) |
Rule set '…' cannot be used: it must be a public class implementing CodeRules with a public no-argument constructor | the ruleset class is not public or has no no-argument constructor | public class … and a default constructor |
… a class it uses is not on the generator's classpath; add it to the rules module's dependencies. | a library the rules use is only compileOnly in the rules module | make that library implementation |
| The rule runs but there is no result | a different target, or the file has no place to draw that annotation | Targets; print render() in a test |
| A field rule is not called | the method shape is not (EntitySpec, FieldSpec), or it is a domain file and the shape is (EntitySpec) | API reference |
ensure instead of merge did nothing | the same annotation is already there (@Schema and so on) | merge to add an attribute |
Not reflected in my file (PurchaseOrder.java, a controller) | a developer's file - generated only once | add it by hand as the generation log's notice says (Targets) |
SKIP(user-modified; -Pforce to overwrite) in the generation log | a generator's file edited by hand | move the edit into a rule and use -Pforce |
SKIP(user-owned) in the generation log | a developer's file | normal - edit it yourself |
| The new file has empty lines and no values | an unfilled ${slot} - it becomes an empty line, not an error | unfilledSlots() in a test (usually a misspelled name) |
The new file is ERROR in a Kotlin project | no kt/<target>.tmpl - it does not fall back to Java | Making new files |
The hexagonal files disappeared after writing rules: in env.yml | publisher.rules replaces the bundle | use the build's rules = [...], or write the bundle name too |
A misspelled DSL word of ours (@pi) is silent | an unknown word is not an error, only kept | add a check rule for words that matter (DSL words and model checks) |
Only one file is ERROR after an exception in a rule | the rule threw an exception | use ModelCheck.fail for model problems |
Our rules are not in the TypeScript client (elcore3ts) | intended - team rules apply only to server (Java, Kotlin) generation | for TypeScript, separately in publisher.rules.ts |
| The rule was changed but the result is the same | the rules module was not recompiled (the jar version unchanged), or the file was edited by hand | for a jar, raise the version and use --refresh-dependencies |
When adding a new rule
- The rule id starts with the team prefix (
ps-…) - so it does not clash with a default rule - It is not a feature the DSL already has - delete the rule and see: if the result stays the same, it already exists
- The team's DSL words do not clash with ElastiCORE's words (
@event,@search,@label…) - The
targetand the method shape match - No annotation is built by concatenating strings (
AnnoCode) - It throws no exceptions (
ModelCheck) - For a new file: an empty list when the condition does not hold,
orNamespace,v3/andkt/skeletons,requireSyntaxAnyOf - There is a rule test, and
unfilledSlots()is empty - The team has been told about changes needed in existing developer's files