Why is EclEmma not syncing (MyClass.class)?

I use EclEmma to analyze coverage.

My Java code includes a synchronized (MyClass.class) {} block.

EclEmma says this is only partially covered by the event, although I do have a unit test in which one thread is accessing and the other thread is blocked.

Is it possible to get full synchronization coverage with EclEmma?

Is there any way to annotate the code to tell EclEmma to give this line full coverage?

Regards Roger

+7
java concurrency synchronized code-coverage emma
source share
3 answers

I'm not sure you can get full coverage, as issue 2939804 reports:

EMMA always marks synchronized(..) as partially covered

Examples:

 synchronized (lock) // partially covered (yellow line in EclEmma) { // ... } synchronized (this) // partially covered (yellow line in EclEmma) { // ... } 

Maybe another tool ( like Cobertura ) will give a different result? (I have not tested it recently).


Update December 2012 (over 2 years later):

Nathan D Ryan reports :

synchronized will turn green if the synchronized block contains the code that the object monitor is waiting for, and the test interrupts the wait stream.

After a little experiment, I was able to achieve full coverage of the synchronized string if the synchronized block terminated normally and terminated abruptly due to an exception.

+6
source share

EclEmma uses Jacoco to analyze coverage.

As explained in Jacoco's (currently non-existent) JAVAC.SYNC filter option , the behavior is the result of bytecode generated for synchronized blocks:

The synchronized Java block is compiled into two bytecode commands: MONITORENTER at the beginning and MONITOREXIT at the end of the block.

In order to ensure that the monitor is released, an exception handler is installed in any case that points to another MONITOREXIT statement. This exception handler block usually causes a partial coverage of the line, which makes no sense from the point of view of the source code.

A related issue, Jacoco issue 245 explains how exceptions can be raised to cover full coverage if desired, which is also explained by @ nathan- Ryan:

  • One test that usually runs a synchronized block
  • The second test, which throws (and therefore expects) an exception from the synchronized block.
+1
source share

I believe the problem is MyClass.class , which is apparently implemented using

http://emma.sourceforge.net/faq.html#q.fractional.examples

Implicit branches due to hidden class .forName (). This case is rather unfortunate because it is quite common, but the programmer has almost no control over it.

Since Class.forName () can throw checked exceptions, the compiler emits a catch block that cancels them as unmanaged. This blocking block is almost never carried out in practice, but it manages to mark the line as a partial coating.

I missed this on first reading.

I will try to rewrite my code to get full coverage.

/ Roger

0
source share

All Articles