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> > 14*7e63c127SSorin Basca <a href="index.html" class="el_group">Documentation</a> > 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 — for example for report 39*7e63c127SSorin Basca generation — 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 — e.g. different method ordering or additional branches — 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> © ${copyright.years} Mountainminds GmbH & Co. KG and Contributors 180*7e63c127SSorin Basca</div> 181*7e63c127SSorin Basca 182*7e63c127SSorin Basca</body> 183*7e63c127SSorin Basca</html> 184