pxb1988/dex2jar · error · RecognitionException

RecognitionException on invalid annotation element keyword…

Error message

RecognitionException on invalid annotation element keyword (expected 's')

What it means

The sAnnotationElement string alternative requires the keyword 's' followed by '=' and a STRING, storing the element via unEscapeString. The guard if(!"s".contains($xid.text)){ throw new RecognitionException(input); } throws when the ID before '=' is not exactly 's' (Jasmin.g:1043). Like the 'e'/'c' variants, the RecognitionException is used for grammar backtracking; surfacing it to the user means none of the element alternatives accepted the keyword.

Solutions

  1. Use the exact keyword 's' for string annotation elements: 's = "text"' inside the .annotation block
  2. Lowercase the keyword (the contains check is case-sensitive against "s")
  3. If the value is not a string, pick the correct alternative keyword: 'e' enum, 'c' class, B/Z/S/C/I/J tokens for primitives
  4. Re-dump the method from the dex with a d2j-compatible tool so annotation elements are emitted in the accepted syntax

Example fix

// before
string = "hello"

// after
s = "hello"
Defensive patterns

Strategy: validation

Validate before calling

// verify string annotation elements are written with keyword 's'
Pattern strElem = Pattern.compile("\\s*([A-Za-z_][\\w$]*)\\s*=\\s*\"([^\"]*)\"\\s*$");
Matcher m = strElem.matcher(jasminSource);
while (m.find()) {
    if (!m.group(1).equals("s")) {
        throw new IllegalArgumentException("string annotation element must use keyword 's', found '" + m.group(1) + "'");
    }
}

Try / catch

try {
    new Jasmin(new StringReader(jasminSource)).parse();
} catch (RecognitionException e) {
    throw new JasminSyntaxException("String annotation elements must be 's = \"...\"'", e);
}

Prevention

When it happens

Trigger: An annotation element in a Jasmin .j file where a string value follows 'name = ' but the keyword ID is not 's', e.g. 'strvalue = "hello"' or 'string = "hello"' inside a '.annotation' block assembled with d2j-jasmin.

Common situations: Files written for other Jasmin dialects that spell the string element differently; manual edits that renamed the element keyword; case mistakes like 'S' (which the grammar treats as the short primitive token, so 'S = "x"' fails here too since the guard expects lowercase 's' followed by a STRING, not the UP_S token path which requires an INT).

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


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/0dfdf40f2992ba24. Report an issue: GitHub.

Appendix: source

Thrown at d2j-jasmin/src/main/antlr3/com/googlecode/d2j/jasmin/Jasmin.g:1043

              	    | '.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); }
           | ARRAY_D '='  (b19=(INT|DOUBLE) {array.add(parseDouble($b19.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_LOW_E c=OBJECT_TYPE '='  ((b1=sWord{  array.add(new String[]{$c.text,unEscape($b1.text)}); }|b2=STRING{  array.add(new String[]{$c.text,unEscapeString($b2.text)}); }|b3=DSTRING{  array.add(new String[]{$c.text,unEscapeString($b3.text)}); })  )+  { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_AND b20=OBJECT_TYPE '=' ARRAY_AT '='  ({currentAnnotationVisitor=new AnnotationNode($b20.text);} sSubannotation{ array.add(currentAnnotationVisitor); })+ { currentAnnotationVisitor.visit($a.text,array); }

View on GitHub (pinned to b5bda4fb49)