Hi,

IMO term "coverage of static fields" is quite vague. And so not clear what 
and why you want to measure? From here and given what is explained below 
any tricks with ClassLoaders sound crazy.

JaCoCo does not record access to fields. It records execution of code that 
initializes fields. Code to initialize static fields is executed when class 
is initialized. So behavior that you observe is correct one, because class 
is initialized only once.

JaCoCo doesn't introduce any new ClassLoaders into application and doesn't 
do any tricks with existing ones.

If two ClassLoaders load class (not return already loaded class), then at 
runtime these two classes are different, with all the consequences. 
Including two initializations of two classes, memory allocation in JVM to 
represent each, two instrumentations, etc. Not counting that this might be 
not expected by your application and tests and hence they might work 
incorrectly - e.g. usage of instance of one class as an argument to the 
equals method of another class will give you false even if 
getClass().getName() is the same, classes were loaded from the same class 
file on disk and have the same code:

  class Foo {
    public boolean equals(Object o) {
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      ...
    }
  }

As far as JaCoCo concerned: if at runtime you have two different classes 
that are actually the same code loaded by different class loaders, JaCoCo 
knows that their code is the same thanks to 
http://www.jacoco.org/jacoco/trunk/doc/classids.html So recorded coverage 
will be stored in a single place, even if there will be two 
instrumentations.

Hope this helps.


Evgeny

On Tuesday, August 29, 2017 at 11:55:52 AM UTC+2, José Carlos de Campos 
wrote:
>
> Hi,
>
> I found the methods dump(true) 
> <http://www.jacoco.org/jacoco/trunk/doc/api/org/jacoco/agent/rt/IAgent.html#dump(boolean)>
>  
> or reset() 
> <http://www.jacoco.org/jacoco/trunk/doc/api/org/jacoco/agent/rt/IAgent.html#reset()>
>  
> of IAgent 
> <http://www.jacoco.org/jacoco/trunk/doc/api/org/jacoco/agent/rt/IAgent.html> 
> class very useful when we want
> to get, for example, periodically coverage. However, I also found that 
> both methods
> do not work I was expecting, special for classes with static fields.
>
> Let's suppose we have the following class:
>
> 1. public class PublicStaticFields {
>
> 2.  public static String className = 
> PublicStaticFields.class.getCanonicalName();
>
>     public static String s;
>
>     static {
> 5.    s = "SsS";
> 6.  }   }
>
>
> and the following test class which achieves 100% line coverage.
>
> import static org.junit.Assert.assertEquals;import static 
> org.junit.Assert.assertNotNull;
> import org.junit.Test;
> public class TestPublicStaticFields {
>
>   @Test
>   public void test1() {
>     assertEquals(PublicStaticFields.class.getCanonicalName(), 
> PublicStaticFields.className);
>     assertEquals("SsS", PublicStaticFields.s);
>   }
>
>   @Test
>   public void test2() {
>     // empty
>   }
>
>   @Test
>   public void test3() {
>     assertEquals(PublicStaticFields.class.getCanonicalName(), 
> PublicStaticFields.className);
>     assertEquals("SsS", PublicStaticFields.s);
>   }
>
>   @Test
>   public void test4() {
>     assertNotNull(new PublicStaticFields());
>   }}
>
>
> Now, suppose we want some periodically coverage. To keep the example 
> simple, let's
> assume periodically as per test case. I.e., every time a test case 
> finishes, coverage
> is collected and dumped. (something similar to what sonar-jacoco-listeners 
> <https://github.com/SonarSource/sonar-java/blob/master/sonar-jacoco-listeners/src/main/java/org/sonar/java/jacoco/JacocoController.java>
>  does)
>
> For this example we should get
>
>    - 3 lines covered by test1 (lines 2, 5, and 6)
>    - 0 lines covered by test2
>    - 3 lines covered by test3 (lines 2, 5, and 6)
>    - 4 lines covered by test4 (lines 1, 2, 5, 6)
>
> however we get:
>
>    - 3 lines covered by test1 (lines 2, 5, and 6) : As expected
>    - 0 lines covered by test2 : As expected
>    - 0 lines covered by test3 : Lines 2, 5, and 6 should have been covered
>    - 1 line covered by test4 (line 1) : Lines 2, 5, and 6 should have 
>    been covered as well
>    
> I do not think there is any bug in methods dump or reset of class IAgent, 
> I just found it a bit
> odd that every time we dump/reset coverage we lost coverage of static 
> fields.
>
> As far I know, the only option to get coverage data of static fields per 
> test case is by loading
> all classes under test with a custom classloader. And I don't think JaCoCo 
> implements its
> own classloader, so it is not surprising that we lose track of coverage of 
> static fields. Please
> correct me if JaCoCo actually implements is own classloader.
>
> Any thoughts on this? Would a JaCoCo's custom classloader be able to 
> address the above
> scenario? What would the drawbacks be? As far I understood, classes get 
> instrumented when
> they are loaded, assuming they will be reloaded several times, would that 
> mean they would
> have to be instrumented several times as well? (I wonder how much would 
> that affect JaCoCo's
> runtime).
>
>
> --
> Thanks in advance,
> Jose
>

-- 
You received this message because you are subscribed to the Google Groups 
"JaCoCo and EclEmma Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jacoco/5f1d2457-15eb-4d67-a178-667a28ac88e3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to