6. Defining the instrumentation set

6.1. How EMMA determines which classes get instrumented

Although EMMA's instrumentation is very fast (it is usually fast enough so that the overall processing time is dominated by file I/O), the key to making EMMA into an even faster tool for individual development is to make EMMA do just the right amount of work, i.e. define the right instrumentation set of classes.

Understanding what gets instrumented is also important for another reason: EMMA coverage reports are based exclusively on the classes in the instrumentation set as implied by coverage metadata.

Instrumentation set. The set of classes that get instrumented in a given invocation of a tool like <instr>/instr or <emmajava>/emmarun is determined by the following rules:

  1. First, a set of classes eligible for instrumentation is determined by an instrumentation path. For <instr>/instr this is set via an explicit option and for <emmajava>/emmarun it is the same as the application classpath. Note that only Java classes contain executable code and are eligible for instrumentation: Java interfaces are never instrumented by EMMA[4].
  2. Next, the set of eligible classes as determined by the above step can be further narrowed down by a set of coverage inclusion and exclusion filters.
  3. Finally,

    • in the offline processing mode, all remaining eligible classes are in fact instrumented and added to the metadata;
    • in the on-the-fly processing mode, <emmajava>/emmarun behavior with respect to the remaining eligible classes depends on whether the full classpath scan mode (fullmetadata (-f) option) is turned on:

      • by default, this mode is not on and only the classes actually used by the application are instrumented and added to the coverage metadata (this happens on demand);
      • if this mode is on, all remaining eligible classes are added to the metadata (this happens before the application starts running).

What this means in practice is that you choose the right set of class directories and archives via the instrumentation path option and then narrow it further down via a number of coverage filters, described next.

[4] Strictly speaking, Java interfaces can contain executable bytecode, but it usually corresponds to field initializer expressions that execute unconditionally when the interface is loaded.