xref: /aosp_15_r20/external/jacoco/org.jacoco.doc/docroot/doc/classids.html (revision 7e63c1270baf9bfa84f5b6aecf17bd0c1a75af94)
1*7e63c127SSorin Basca<?xml version="1.0" encoding="UTF-8" ?>
2*7e63c127SSorin Basca<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3*7e63c127SSorin Basca<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
4*7e63c127SSorin Basca<head>
5*7e63c127SSorin Basca  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6*7e63c127SSorin Basca  <link rel="stylesheet" href="resources/doc.css" charset="UTF-8" type="text/css" />
7*7e63c127SSorin Basca  <link rel="shortcut icon" href="resources/report.gif" type="image/gif" />
8*7e63c127SSorin Basca  <title>JaCoCo - Class Ids</title>
9*7e63c127SSorin Basca</head>
10*7e63c127SSorin Basca<body>
11*7e63c127SSorin Basca
12*7e63c127SSorin Basca<div class="breadcrumb">
13*7e63c127SSorin Basca  <a href="../index.html" class="el_report">JaCoCo</a> &gt;
14*7e63c127SSorin Basca  <a href="index.html" class="el_group">Documentation</a> &gt;
15*7e63c127SSorin Basca  <span class="el_source">Class Ids</span>
16*7e63c127SSorin Basca</div>
17*7e63c127SSorin Basca<div id="content">
18*7e63c127SSorin Basca
19*7e63c127SSorin Basca<h1>Class Ids</h1>
20*7e63c127SSorin Basca
21*7e63c127SSorin Basca<p>
22*7e63c127SSorin Basca  As JaCoCo's class identifiers are sometimes causing confusion this chapter
23*7e63c127SSorin Basca  answers the concepts and common issues with class ids in FAQ style format.
24*7e63c127SSorin Basca</p>
25*7e63c127SSorin Basca
26*7e63c127SSorin Basca<h3>What are class ids and how are they created?</h3>
27*7e63c127SSorin Basca<p>
28*7e63c127SSorin Basca  Class ids are 64-bit integer values, for example
29*7e63c127SSorin Basca  <code>0x638e104737889183</code> in hex notation. Their calculation is
30*7e63c127SSorin Basca  considered an implementation detail of JaCoCo. Currently ids are created with
31*7e63c127SSorin Basca  a CRC64 checksum of the raw class file.
32*7e63c127SSorin Basca</p>
33*7e63c127SSorin Basca
34*7e63c127SSorin Basca<h3>What are class ids used for?</h3>
35*7e63c127SSorin Basca<p>
36*7e63c127SSorin Basca  Class ids are used to unambiguously identify Java classes. At runtime execution
37*7e63c127SSorin Basca  data is sampled for every loaded class and typically stored to
38*7e63c127SSorin Basca  <code>*.exec</code> files. At analysis time &mdash; for example for report
39*7e63c127SSorin Basca  generation &mdash; the class ids are used to relate analyzed classes with the
40*7e63c127SSorin Basca  execution data.
41*7e63c127SSorin Basca</p>
42*7e63c127SSorin Basca
43*7e63c127SSorin Basca<h3>What are the advantages of JaCoCo class ids?</h3>
44*7e63c127SSorin Basca<p>
45*7e63c127SSorin Basca  The concept of class ids allows distinguishing different versions of classes,
46*7e63c127SSorin Basca  for example when multiple versions of an application are deployed to an
47*7e63c127SSorin Basca  application server or different versions of libraries are included.
48*7e63c127SSorin Basca</p>
49*7e63c127SSorin Basca<p>
50*7e63c127SSorin Basca  Also class ids are the prerequisite for JaCoCo's minimal runtime-overhead and
51*7e63c127SSorin Basca  small <code>*.exec</code> files even for very large applications under test.
52*7e63c127SSorin Basca</p>
53*7e63c127SSorin Basca
54*7e63c127SSorin Basca<h3>What is the disadvantage of JaCoCo class ids?</h3>
55*7e63c127SSorin Basca<p>
56*7e63c127SSorin Basca  The fact that class ids identify a specific version of a class causes problems
57*7e63c127SSorin Basca  in setups where different classes are used at runtime and at analysis time.
58*7e63c127SSorin Basca</p>
59*7e63c127SSorin Basca
60*7e63c127SSorin Basca<h3>What happens if different classes are used at runtime and at analysis time?</h3>
61*7e63c127SSorin Basca<p>
62*7e63c127SSorin Basca  In this case execution data cannot be related to the analyzed classes. As a
63*7e63c127SSorin Basca  consequence such classes are reported with 0% coverage.
64*7e63c127SSorin Basca</p>
65*7e63c127SSorin Basca
66*7e63c127SSorin Basca<h3>How can I detect that I have a problem with class ids?</h3>
67*7e63c127SSorin Basca<p>
68*7e63c127SSorin Basca  The typical symptom of class id mismatch is classes not shown as covered
69*7e63c127SSorin Basca  although they have been executed during the test. This situation can be easily
70*7e63c127SSorin Basca  detected e.g. in the HTML report: Open the <i>Sessions</i> page with the link
71*7e63c127SSorin Basca  on the top-right corner. You see a list of all classes where execution data
72*7e63c127SSorin Basca  has been collected for. Find the class in questions and check whether the
73*7e63c127SSorin Basca  entry has a link to the corresponding coverage report page. If the entry is
74*7e63c127SSorin Basca  not linked this means there is a class id mismatch between the class used at
75*7e63c127SSorin Basca  runtime and the class provided to create the report.
76*7e63c127SSorin Basca</p>
77*7e63c127SSorin Basca
78*7e63c127SSorin Basca<h3>What can cause different class ids?</h3>
79*7e63c127SSorin Basca<p>
80*7e63c127SSorin Basca  Class ids are identical for the exact same class file only (byte-by-byte).
81*7e63c127SSorin Basca  There is a couple of reasons why you might get different class files. First
82*7e63c127SSorin Basca  compiling Java source files will result in different class files if you use
83*7e63c127SSorin Basca  a different tool chain:
84*7e63c127SSorin Basca</p>
85*7e63c127SSorin Basca<ul>
86*7e63c127SSorin Basca  <li>Different compiler vendor (e.g. Eclipse vs. Oracle JDK)</li>
87*7e63c127SSorin Basca  <li>Different compiler versions</li>
88*7e63c127SSorin Basca  <li>Different compiler settings (e.g. debug vs. non-debug) </li>
89*7e63c127SSorin Basca</ul>
90*7e63c127SSorin Basca<p>
91*7e63c127SSorin Basca  Also post-processing class files (obfuscation, AspectJ, etc.) will typically
92*7e63c127SSorin Basca  change the class files. JaCoCo will work well if you simply use the same class
93*7e63c127SSorin Basca  files for runtime as well as for analysis. So the tool chain to create these
94*7e63c127SSorin Basca  class files does not matter.
95*7e63c127SSorin Basca</p>
96*7e63c127SSorin Basca<p>
97*7e63c127SSorin Basca  Even if the class files on the file system are the same there is possible that
98*7e63c127SSorin Basca  classes seen by the JaCoCo runtime agent are different anyways. This typically
99*7e63c127SSorin Basca  happens when another Java agent is configured <i>before</i> the JaCoCo agent
100*7e63c127SSorin Basca  or special class loaders pre-process the class files. Typical candidates are:
101*7e63c127SSorin Basca</p>
102*7e63c127SSorin Basca<ul>
103*7e63c127SSorin Basca  <li>Mocking frameworks</li>
104*7e63c127SSorin Basca  <li>Application servers</li>
105*7e63c127SSorin Basca  <li>Persistence frameworks</li>
106*7e63c127SSorin Basca</ul>
107*7e63c127SSorin Basca
108*7e63c127SSorin Basca<h3>What workarounds exist to deal with runtime-modified classes?</h3>
109*7e63c127SSorin Basca<p>
110*7e63c127SSorin Basca  If classes get modified at runtime in your setup there are some workarounds to
111*7e63c127SSorin Basca  make JaCoCo work anyways:
112*7e63c127SSorin Basca</p>
113*7e63c127SSorin Basca<ul>
114*7e63c127SSorin Basca  <li>If you use another Java agent make sure the <a href="agent.html">JaCoCo
115*7e63c127SSorin Basca      agent</a> is specified at first in the command line. This way the JaCoCo
116*7e63c127SSorin Basca      agent should see the original class files.</li>
117*7e63c127SSorin Basca  <li>Specify the <code>classdumpdir</code> option of the
118*7e63c127SSorin Basca      <a href="agent.html">JaCoCo agent</a> and use the dumped classes at report
119*7e63c127SSorin Basca      generation. Note that only loaded classes will be dumped, i.e. classes not
120*7e63c127SSorin Basca      executed at all will not show-up in your report as not covered.</li>
121*7e63c127SSorin Basca  <li>Use <a href="offline.html">offline instrumentation</a> before you run your
122*7e63c127SSorin Basca      tests. This way classes get instrumented by JaCoCo before any runtime
123*7e63c127SSorin Basca      modification can take place. Note that in this case the report has to be
124*7e63c127SSorin Basca      generated with the <i>original</i> classes, not with instrumented ones.</li>
125*7e63c127SSorin Basca</ul>
126*7e63c127SSorin Basca
127*7e63c127SSorin Basca<h3>Why can't JaCoCo simply use the class name to identify classes?</h3>
128*7e63c127SSorin Basca<p>
129*7e63c127SSorin Basca  To understand why JaCoCo can't rely on class names we need to have a look at
130*7e63c127SSorin Basca  the way how JaCoCo measures code coverage.
131*7e63c127SSorin Basca</p>
132*7e63c127SSorin Basca<p>
133*7e63c127SSorin Basca  JaCoCo tracks execution with so called <i>probes</i>. Probes are additional
134*7e63c127SSorin Basca  byte code instructions inserted in the original class file which will note
135*7e63c127SSorin Basca  when they are executed and report this to the JaCoCo runtime. This process is
136*7e63c127SSorin Basca  called <i>instrumentation</i>. To keep the runtime overhead minimal, only a
137*7e63c127SSorin Basca  few probes are inserted at "strategic" places. These probe positions are
138*7e63c127SSorin Basca  determined by <a href="flow.html">analyzing the control flow</a> of all
139*7e63c127SSorin Basca  methods of a class. As a result every instrumented class produces a list of
140*7e63c127SSorin Basca  <code>n</code> boolean flags indicating whether the probe has been executed or
141*7e63c127SSorin Basca  not. A JaCoCo <code>*.exec</code> file simply stores a boolean array per
142*7e63c127SSorin Basca  class id.
143*7e63c127SSorin Basca</p>
144*7e63c127SSorin Basca<p>
145*7e63c127SSorin Basca  At analysis time, for example for report generation, the <code>*.exec</code>
146*7e63c127SSorin Basca  file is used to get information about probe execution status. But as probes
147*7e63c127SSorin Basca  are stored in a plain boolean array there is no information like corresponding
148*7e63c127SSorin Basca  methods or lines. To retrieve this information we need the original class
149*7e63c127SSorin Basca  files and perform the exact same control flow analysis than at instrumentation
150*7e63c127SSorin Basca  time. Because this is a deterministic process we get the same probe positions.
151*7e63c127SSorin Basca  With this information we can now interfere the execution status of every
152*7e63c127SSorin Basca  single instruction and branch of a method. Using the debug information
153*7e63c127SSorin Basca  embedded in the class files we can also calculate line coverage.
154*7e63c127SSorin Basca</p>
155*7e63c127SSorin Basca<p>
156*7e63c127SSorin Basca  If we would use just slightly different classes at analysis time than at
157*7e63c127SSorin Basca  runtime &mdash; e.g. different method ordering or additional branches &mdash;
158*7e63c127SSorin Basca  we would end-up with different probes. For example the probe at index
159*7e63c127SSorin Basca  <code>i</code> would be in method <code>a()</code> and not in method
160*7e63c127SSorin Basca  <b>b()</b>. Obviously this will create random coverage results.
161*7e63c127SSorin Basca</p>
162*7e63c127SSorin Basca
163*7e63c127SSorin Basca<h3>Why do I get an error when I try to analyze multiple versions of the same
164*7e63c127SSorin Basca    class with a group?</h3>
165*7e63c127SSorin Basca<p>
166*7e63c127SSorin Basca  JaCoCo always analyzes a set of class as a group. The group is used to
167*7e63c127SSorin Basca  aggregate data for source files and packages (both can contain multiple
168*7e63c127SSorin Basca  classes). Within the reporting API classes are identified by their fully
169*7e63c127SSorin Basca  qualified name (e.g. to create stable file names in the HTML reports).
170*7e63c127SSorin Basca  Therefore it is not possible to include two different classes with the same
171*7e63c127SSorin Basca  name within a group. Anyhow it is possible to analyze different versions of
172*7e63c127SSorin Basca  class files in separate groups, for example the <a href="ant.html#report">Ant
173*7e63c127SSorin Basca  report task</a> can be configured with multiple groups.
174*7e63c127SSorin Basca</p>
175*7e63c127SSorin Basca
176*7e63c127SSorin Basca</div>
177*7e63c127SSorin Basca<div class="footer">
178*7e63c127SSorin Basca  <span class="right"><a href="${jacoco.home.url}">JaCoCo</a> ${qualified.bundle.version}</span>
179*7e63c127SSorin Basca  <a href="license.html">Copyright</a> &copy; ${copyright.years} Mountainminds GmbH &amp; Co. KG and Contributors
180*7e63c127SSorin Basca</div>
181*7e63c127SSorin Basca
182*7e63c127SSorin Basca</body>
183*7e63c127SSorin Basca</html>
184