pxb1988/dex2jar · error · RecognitionException
RecognitionException on invalid annotation element keyword…
Error message
RecognitionException on invalid annotation element keyword (expected 'e')
What it means
In Jasmin.g the sAnnotationElement rule accepts several alternatives that all start with an ID token; each alternative guards the ID text with a check like if(!"e".contains($xid.text)){ throw new RecognitionException(input); }. This error fires when the parser matched the enum-element alternative (the one expecting the keyword 'e' followed by OBJECT_TYPE '=' sWord) but the ID text is not 'e', so a RecognitionException is thrown to force the parser to try the other alternatives. It is a grammar-level backtracking mechanism rather than a normal runtime error, but when no alternative matches, the user sees it as a parse failure.
Solutions
- Fix the .j file so the enum annotation element uses the exact keyword 'e' before the type and '=' (e.g. 'e = Lcom/Type;.FIELD V')
- Check which alternative the element actually belongs to and use the matching keyword: 'c' for class desc, 's' for string, 'B/Z/S/C/I/J' tokens for primitives
- If the file comes from another tool (Soot/dx), re-emit the annotation with d2j-jasmin's accepted syntax or convert the source with dexdump/baksmali instead
- If you control the grammar, replace the ID-plus-'contains' guard alternatives with explicit token keywords so the error points at the real offending token
Example fix
// before (in .j file inside .annotation) kind = LMyEnum;.VALUE X // after e = LMyEnum;.VALUE X
Defensive patterns
Strategy: validation
Validate before calling
// before invoking the assembler, scan .annotation elements in the .j text
Pattern enumElem = Pattern.compile("^\\s*(?!e\\s*=)[A-Za-z_][A-Za-z0-9_$]*\\s*=\\s*L[A-Za-z0-9_$/;.;-]+\\.\\S+\\s+\\S+$", Pattern.MULTILINE);
Matcher m = enumElem.matcher(jasminSource);
if (m.find()) {
throw new IllegalArgumentException("line " + countLine(jasminSource, m.start()) +
": enum annotation element must use keyword 'e', found '" + m.group(1) + "'");
} Try / catch
try {
new Jasmin(new StringReader(jasminSource)).parse();
} catch (RecognitionException e) {
throw new JasminSyntaxException("Unsupported annotation element keyword: use 'e', 'c', 's', or primitive tokens B/Z/S/C/I/J", e);
} Prevention
- Use only the single-letter element keywords d2j-jasmin accepts: e, c, s, and tokens B/Z/S/C/I/J
- Generate .j files with a d2j-compatible dumper rather than hand-writing annotation blocks
- Lint .annotation blocks with a regex for keyword '= value' shape before assembling
- Keep letter case exact: guards compare lowercase 'e'/'c'/'s'
When it happens
Trigger: Assembling a Jasmin (.j) file whose .annotation element uses an enum element but the element keyword token before OBJECT_TYPE is not exactly 'e', e.g. writing 'enumvalue = LSomeEnum;.FIELD SomeValue' or an empty/mistyped keyword inside a '.annotation' block fed to the Jasmin assembler (AsmV3 jasmin assembler, sAnnotationElement rule at Jasmin.g:1040).
Common situations: Hand-written or Soot-produced Jasmin that uses an annotation element keyword other than the single letters this grammar accepts (e/c/s/B/Z/S/C/I/J); typos in the element kind; Jasmin dialects (e.g. original Soot jasmin syntax) that spell the enum element differently than d2j-jasmin expects.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- RecognitionException on invalid annotation element keyword…
- RecognitionException on invalid annotation element keyword…
- Fail to assemble
- can't pase string
- not support access flags " + name
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/95dd062c713c5557.
Report an issue: GitHub.
Appendix: source
Thrown at d2j-jasmin/src/main/antlr3/com/googlecode/d2j/jasmin/Jasmin.g:1040
| '.int_kind' a=STRING b=INT {$nn=unEscapeString($a.text); $v=parseInt($b.text);}
| '.long_kind' a=STRING b=(INT|LONG) {$nn=unEscapeString($a.text); $v=parseLong($b.text);}
| '.float_kind' a=STRING b=INT {$nn=unEscapeString($a.text); $v=parseFloat($b.text);}
| '.doub_kind' a=STRING b=(INT|LONG) {$nn=unEscapeString($a.text); $v=parseDouble($b.text);}
| '.str_kind' a=STRING b=STRING {$nn=unEscapeString($a.text); $v=unEscapeString($b.text);}
| '.enum_kind' a=STRING b=STRING {$nn=unEscapeString($a.text); String on[]=parseOwnerAndName($b.text);$v=new String[]{on[0],on[1]};}
| '.cls_kind' a=STRING b=STRING {$nn=unEscapeString($a.text); $v=Type.getType(unEscapeString($b.text));}
| '.arr_kind' a=STRING {List<Object> array=new ArrayList<>();} (t=sAnnotationElementSoot{array.add($t.v);})* '.end' '.arr_elem' {$nn=unEscapeString($a.text); $v=array;}
| '.ann_kind' a=STRING q=sSubannotationSoot '.end' '.annot_elem' {$nn=unEscapeString($a.text); $v=$q.v;})
;
sSubannotationSoot returns[AnnotationNode v]
: '.annotation' a=STRING { $v=new AnnotationNode(unEscapeString($a.text)); }
(t=sAnnotationElementSoot {$v.visit($t.nn,$t.v);} )*
'.end' '.annotation'
;
sAnnotationElement @init{List<Object> array = new ArrayList<Object>(); AnnotationNode _t= currentAnnotationVisitor;}
: a=sId (
xid=ID { if(!"e".contains($xid.text)){ throw new RecognitionException(input);} } c=OBJECT_TYPE '=' b=sWord { _t.visit($a.text,new String[]{$c.text,$b.text}); }
| AT b2=OBJECT_TYPE '=' { currentAnnotationVisitor=new AnnotationNode($b2.text);} sSubannotation { _t.visit($a.text,currentAnnotationVisitor); }
| xid=ID { if(!"c".contains($xid.text)){ throw new RecognitionException(input);} } '=' b1=sClassDesc { currentAnnotationVisitor.visit($a.text,Type.getType($b1.text)); }
| xid=ID { if(!"s".contains($xid.text)){ throw new RecognitionException(input);} } '=' b3=STRING { currentAnnotationVisitor.visit($a.text,unEscapeString($b3.text)); }
| UP_B '=' b4=INT { currentAnnotationVisitor.visit($a.text,(byte)parseInt($b4.text)); }
| UP_Z '=' b5=INT { currentAnnotationVisitor.visit($a.text,0!=parseInt($b5.text)); }
| UP_S '=' b6=INT { currentAnnotationVisitor.visit($a.text,(short)parseInt($b6.text)); }
| UP_C '=' b7=INT { currentAnnotationVisitor.visit($a.text,(char)parseInt($b7.text)); }
| UP_I '=' b8=INT { currentAnnotationVisitor.visit($a.text,parseInt($b8.text)); }
| UP_J '=' b9=(INT|LONG) { currentAnnotationVisitor.visit($a.text,parseLong($b9.text)); }
| UP_F '=' b10=(INT|FLOAT|DOUBLE) { currentAnnotationVisitor.visit($a.text,parseFloat($b10.text)); }
| UP_D '=' b11=(INT|FLOAT|DOUBLE) { currentAnnotationVisitor.visit($a.text,parseDouble($b11.text)); }
| ARRAY_B '=' (b12=INT {array.add((byte)parseInt($b12.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_Z '=' (b13=INT {array.add(0!=parseInt($b13.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_S '=' (b14=INT {array.add((short)parseInt($b14.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_C '=' (b15=INT {array.add((char)parseInt($b15.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_I '=' (b16=INT {array.add(parseInt($b16.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_J '=' (b17=(INT|LONG) {array.add(parseLong($b17.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
| ARRAY_F '=' (b18=(INT|FLOAT|DOUBLE) {array.add(parseFloat($b18.text));} )+ { currentAnnotationVisitor.visit($a.text,array); }
View on GitHub (pinned to b5bda4fb49)