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[]){
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.
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[]){
}
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 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
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
}
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[]){
}
}
When will this Bug be fixed? I have the same problem with my antlr parser
Cheers Andy
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