From working with EMMA I have noticed that it fails to instrument correctly causing the class to become mangled. Below is a simple example highlighting this issue.
public void showProblem() {
try {
for (int i = 0; i > 10; i++) {
System.out.println(i);
}
} catch (final Throwable e) {
System.err.println(e);
}
}
public void showProblem()
{
boolean[][] tmp3_0 = $VRc; if (tmp3_0 == null) tmp3_0; boolean[] arrayOfBoolean = $VRi()[1]; int i = 0; arrayOfBoolean[0] = true; tmpTernaryOp = tmp3_0;
try
{
do
{
Throwable e;
System.out.println(e);
e++; arrayOfBoolean[1] = true; arrayOfBoolean[2] = true; } while (e > 10); arrayOfBoolean[3] = true;
}
catch (Throwable localThrowable1)
{
System.err.println(localThrowable1); arrayOfBoolean[4] = true;
}
arrayOfBoolean[5] = true;
}
Notice that it is attempting to increment e
of type Throwable
and using this within the while
loop.
I have found that by moving the try catch logic within the for
loop it resolves this. As highlighted in the below code.
public void showProblem() {
for (int i = 0; i > 10; i++) {
try {
System.out.println(i);
} catch (final Throwable e) {
System.err.println(e);
}
}
}
public void showProblem()
{
boolean[][] tmp3_0 = $VRc; if (tmp3_0 == null) tmp3_0; boolean[] arrayOfBoolean = $VRi()[1]; int i = 0;
Throwable e;
arrayOfBoolean[0] = true; tmpTernaryOp = tmp3_0;
do {
try { System.out.println(i); arrayOfBoolean[1] = true;
} catch (Throwable localThrowable1) {
System.err.println(localThrowable1); arrayOfBoolean[2] = true;
}
i++; arrayOfBoolean[3] = true; arrayOfBoolean[4] = true; } while (i > 10);
arrayOfBoolean[5] = true;
}
Has anyone else experienced these issues?
So it turned out that the problem was to do with the debug information that eclipse was building into the classes. This was observed when using the Android generated ant scripts to execute javac
and similarly caused the problem. Disabling this enabled EMMA to successfully process the class files.
I hope this information will help others.
I have tested under Windows XP with Java JRE 1.6.0_35 and EMMA 2.0.5312 without any problems. For me the decompiled code (using JAD) looks like this:
public void showProblem()
{
boolean aflag[] = ($VRc != null ? $VRc : $VRi())[2];
try
{
int i = 0;
aflag[0] = true;
do
{
aflag[2] = true;
if (i > 10)
{
System.out.println(i);
i++;
aflag[1] = true;
} else
{
break;
}
} while (true);
aflag[3] = true;
}
catch (Throwable throwable)
{
System.err.println(throwable);
aflag[4] = true;
}
aflag[5] = true;
}
P.S.: I think in your code sample you actually wanted to use i < 10
in the for
loop, not i > 10
, didn't you? ;-) Anyway, I used your code just as to make sure to reproduce your situation.