Menu

Instr fails if class contains \1\123

Developers
2009-05-05
2013-05-09
  • Benjamin Schwertfeger

    I had a generated antlr-parser and this file contains a string \1\123. If I instrument this class it seems to work. While running the coverage, emma exits the process while reading this class with:

    Exception in thread "main" java.lang.NoSuchMethodError: com.vladium.emma.rt.RT.S([[ZLjava/lang/String;J)V
        at Test.$VRi(Test.java)
        at Test.<clinit>(Test.java)

    My smalles example is
    public class Test {
        String bad="\1\123";
        public static void main(String args[]){
           
        }
    }

    My emma-Version is 2.0.5312 EclEmma Fix 1 from eclemma. But the same result is with 2.0.5312 from http://lukas.zapletalovi.com/blog:emma_code_coverage_tool_fixed_version on x86_64.

    Is the Problem known, or can someone give me a hint, how to solve it?

    Regards,
    Ben

     
    • Marc R. Hoffmann

      Hi Ben,

      it looks like you identified a very simple example for the following bug:

      https://sourceforge.net/tracker/?func=detail&aid=1977924&group_id=108932&atid=651897

      The missing method should actually be "com.vladium.emma.rt.RT.r". If you disassamble the instrumented class with javap you will see that the method constant actually points to the string containing "\1\123", therefore "r" is replaced by "\1\123".

      Obviously EMMA gets confused by strings starting with \1 and screws up the constant pool in this case.

      BTW, the EclEmma Fix 1 is related to a very different issue with logging.

      Best regards,
      -marc

      ------------------------------------------------------

      Compiled from "BrokenConst.java"
      public class BrokenConst extends java.lang.Object
        SourceFile: "BrokenConst.java"
        minor version: 0
        major version: 49
        Constant pool:
      const #1 = class    #2;    //  BrokenConst
      const #2 = Asciz    BrokenConst;
      const #3 = class    #4;    //  java/lang/Object
      const #4 = Asciz    java/lang/Object;
      const #5 = Asciz    bad;
      const #6 = Asciz    Ljava/lang/String;;
      const #7 = Asciz    <init>;
      const #8 = Asciz    ()V;
      const #9 = Asciz    Code;
      const #10 = Method    #3.#11;    //  java/lang/Object."<init>":()V
      const #11 = NameAndType    #7:#8;//  "<init>":()V
      const #12 = String    #13;    //  S
      const #13 = Asciz    S;
      const #14 = Field    #1.#15;    //  BrokenConst.bad:Ljava/lang/String;
      const #15 = NameAndType    #5:#6;//  bad:Ljava/lang/String;
      const #16 = Asciz    LineNumberTable;
      const #17 = Asciz    LocalVariableTable;
      const #18 = Asciz    this;
      const #19 = Asciz    LBrokenConst;;
      const #20 = Asciz    main;
      const #21 = Asciz    ([Ljava/lang/String;)V;
      const #22 = Asciz    args;
      const #23 = Asciz    [Ljava/lang/String;;
      const #24 = Asciz    SourceFile;
      const #25 = Asciz    BrokenConst.java;
      const #26 = Asciz    Synthetic;
      const #27 = Asciz    $VRc;
      const #28 = Asciz    [[Z;
      const #29 = NameAndType    #27:#28;//  $VRc:[[Z
      const #30 = Field    #1.#29;    //  BrokenConst.$VRc:[[Z
      const #31 = Asciz    com/vladium/emma/rt/RT;
      const #32 = class    #31;    //  com/vladium/emma/rt/RT
      const #33 = Asciz    ([[ZLjava/lang/String;J)V;
      const #34 = NameAndType    #13:#33;//  "S":([[ZLjava/lang/String;J)V    <=== WRONG REFERENCE TO #13
      const #35 = Method    #32.#34;    //  com/vladium/emma/rt/RT."S":([[ZLjava/lang/String;J)V
      const #36 = Asciz    $VRi;
      const #37 = Asciz    ()[[Z;
      const #38 = NameAndType    #36:#37;//  $VRi:()[[Z
      const #39 = Method    #1.#38;    //  BrokenConst.$VRi:()[[Z
      const #40 = String    #2;    //  BrokenConst
      const #41 = Asciz    <clinit>;
      const #42 = long    4397209116073450641l;
      const #44 = Asciz    $VRi;
      const #45 = Asciz    ()[[Z;
      const #46 = class    #28;    //  "[[Z"
      const #47 = Asciz    ConstantValue;
      const #48 = long    933892595777132893l;
      const #50 = Asciz    serialVersionUID;
      const #51 = Asciz    J;

      {
      java.lang.String bad;

      private static final boolean[][] $VRc;
        Synthetic: true

      private static final long serialVersionUID;
        Constant value: long 933892595777132893l  Synthetic: true

      public BrokenConst();
        Code:
         Stack=5, Locals=2, Args_size=1
         0:    getstatic    #30; //Field $VRc:[[Z
         3:    dup
         4:    ifnonnull    11
         7:    pop
         8:    invokestatic    #39; //Method $VRi:()[[Z
         11:    iconst_0
         12:    aaload
         13:    astore_1
         14:    aload_0
         15:    invokespecial    #10; //Method java/lang/Object."<init>":()V
         18:    aload_0
         19:    ldc    #12; //String S
         21:    putfield    #14; //Field bad:Ljava/lang/String;
         24:    aload_1
         25:    iconst_0
         26:    iconst_1
         27:    bastore
         28:    return
        LineNumberTable:
         line 1: 14
         line 3: 18
         line 1: 24
        LocalVariableTable:
         Start  Length  Slot  Name   Signature
         0      11      0    this       LBrokenConst;

      public static void main(java.lang.String[]);
        Code:
         Stack=3, Locals=2, Args_size=1
         0:    getstatic    #30; //Field $VRc:[[Z
         3:    dup
         4:    ifnonnull    11
         7:    pop
         8:    invokestatic    #39; //Method $VRi:()[[Z
         11:    iconst_1
         12:    aaload
         13:    astore_1
         14:    aload_1
         15:    iconst_0
         16:    iconst_1
         17:    bastore
         18:    return
        LineNumberTable:
         line 6: 14
        LocalVariableTable:
         Start  Length  Slot  Name   Signature
         0      1      0    args       [Ljava/lang/String;

      private static {};
        Code:
         Stack=3, Locals=1, Args_size=0
         0:    invokestatic    #39; //Method $VRi:()[[Z
         3:    iconst_2
         4:    aaload
         5:    astore_0
         6:    aload_0
         7:    iconst_0
         8:    iconst_1
         9:    bastore
         10:    return
        Synthetic: true

      private static boolean[][] $VRi();
        Code:
         Stack=5, Locals=0, Args_size=0
         0:    iconst_3
         1:    multianewarray    #46,  1; //class "[[Z"
         5:    dup
         6:    putstatic    #30; //Field $VRc:[[Z
         9:    dup
         10:    iconst_0
         11:    iconst_1
         12:    newarray boolean
         14:    aastore
         15:    dup
         16:    iconst_1
         17:    iconst_1
         18:    newarray boolean
         20:    aastore
         21:    dup
         22:    iconst_2
         23:    iconst_1
         24:    newarray boolean
         26:    aastore
         27:    dup
         28:    ldc    #40; //String BrokenConst
         30:    ldc2_w    #42; //long 4397209116073450641l
         33:    invokestatic    #35; //Method com/vladium/emma/rt/RT."S":([[ZLjava/lang/String;J)V
         36:    areturn
        Synthetic: true

      }

       
    • Benjamin Schwertfeger

      Thank you Marc,
      it really looks like an example for this bug.

      A hack for people with the same problem:
      In my case I replace the String with a concatenation of a non final variable conatining \123 and the generated code. My compiler doesn't optimize this to a constant, so emma can't replace it. The final static is generated by ant and I don't want to change too much.

      public class Test {
      static String part = "\123";
      final static String bad="\1"+part; //initialization is done at runtime to prevent \1\123 in one constant
      public static void main(String args[]){
      }
      }

       
  • Andreas Rytina

    Andreas Rytina - 2012-06-05

    When will this Bug be fixed? I have the same problem with my antlr parser

    Cheers Andy

     
  • Benjamin Klatt

    Benjamin Klatt - 2012-10-19

    Hi,

    the bug is not fixed yet as far as I know. The only chance you have is to exclude the bas code from beeing instrumented.
    There are parameters to do this by the emma command line tool and ANT target and the eclipse integration provides such a filtering in the coverage launch configuration.

    I had the same issue with the buckminster integration necessary to integrate emma for eclipse plugins into the jenkins/hudson continous integration server. However, this integration does not provide such a parameter.
    After some investigation, I found a similar setting that can be placed manually in the launch configuration file.

    I documented this in this article: http://www.bar54.de/blog/2012/10/jenkinsbuckminsteremma-nosuchmethoderror-specify-packages-to-instrument/

    All the best
    Benjamin

     

Log in to post a comment.