blob: d71d029dedc07f52470fff304444f0b15f5e7917 [file] [log] [blame]
Marc R. Hoffmanna2af15d2009-06-07 21:15:05 +00001<?xml version="1.0" encoding="ISO-8859-1" ?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
4<head>
5 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
6 <link rel="stylesheet" href="book.css" charset="ISO-8859-1" type="text/css" />
7 <title>JaCoCo - Implementation Design</title>
8</head>
9<body>
10
11<h1>JaCoCo - Implementation Design</h1>
12
13<p>
14 This is a unordered list of implementation design decisions. Each topic tries
15 to follow this structure:
16</p>
17
18<ul>
19 <li>Problem statement</li>
20 <li>Proposed Solution</li>
21 <li>Alternatives and Discussion</li>
22</ul>
23
24
25<h2>Coverage Analysis Mechanism</h2>
26
27<p class="Note">
28 Coverage information has to be collected at runtime. For this purpose JaCoCo
29 creates instrumented versions of the original class definitions. The
30 instrumentation process happens on-the-fly during class loading using so
31 called Java agents.
32</p>
33
34<p>
35 There are several different approaches to collect coverage information. For
36 each approach different implementation techniques are known. The following
37 diagram gives an overview with the techniques used by JaCoCo highlighted:
38</p>
39
40<ul>
41 <li>Runtime Profiling
42 <ul>
43 <li>Java Virtual Machine Profiler Interface (JVMPI), until Java 1.4</li>
44 <li>Java Virtual Machine Tool Interface (JVMTI), since Java 1.5</li>
45 </ul>
46 </li>
47 <li><b>Instrumentation</b>
48 <ul>
49 <li>Java Source Instrumentation</li>
50 <li><b>Byte Code</b> Instrumentation
51 <ul>
52 <li>Offline
53 <ul>
54 <li>Replace Original Classes In-Place</li>
55 <li>Inject Instrumented Classes into the Class Path</li>
56 </ul>
57 </li>
58 <li><b>On-The-Fly</b>
59 <ul>
60 <li>Special Classloader Implementions or Framework Specific Hooks</li>
61 <li><b>Java Agent</b></li>
62 </ul>
63 </li>
64 </ul>
65 </li>
66 </ul>
67 </li>
68</ul>
69
70<p>
71 Byte code instrumentation is very fast, can be implemented in pure Java and
72 works with every Java VM. On-the-fly instrumentation with the Java agent
73 hook can be added to the JVM without any modification of the target
74 application.
75</p>
76
77<p>
78 The Java agent hook requires at least 1.5 JVMs. For reporting class files
79 compiled with debug information (line numbers) allow a good mapping back to
80 source level. Although some Java language constructs are compiled in a way
81 that the the coverage highlighting leads to unexpected results, especially
82 in case of implicitly generated code like default constructors or control
83 structures for finally statements.
84</p>
85
86<h2>Instrumentation Approach</h2>
87
88<p class="Note">
89 Basic Block
90</p>
91
92<p>
93 Problem: Exceptions
94</p>
95
96<h2>Minimal Java Version</h2>
97
98<p class="Note">
99</p>
100
101
102<h2>Byte Code Manipulation</h2>
103
104<p class="Note">
105 ASM
106</p>
107
108
109<h2>Java Class Identity</h2>
110
111<p class="Note">
112 Each class loaded at runtime needs a unique identity to associate coverage data with.
113 JaCoCo creates such identities by a CRC64 hash code of the raw class definition.
114</p>
115
116<p>
117 In multi-classloader environments the plain name of a class does not
118 unambiguously identify a class. For example OSGi allows to use different
119 versions of the same class to be loaded within the same VM. In complex
120 deployment scenarios the actual version of the test target might be different
121 from current development version. A code coverage report should guarantee that
122 the presented figures have are extracted from a valid test target. A hash code
123 of the class definitions allows a differentiate between classes and versions
124 of a class. The CRC64 hash computation is simple and fast resulting in a small
125 64 bit identifier.
126</p>
127
128<p>
129 The same class definition might be loaded by class loaders which will result
130 in different classes for the Java runtime system. For coverage analysis this
131 distinction should be irrelevant. Class definitions might be altered by other
132 instrumentation based technologies (e.g. AspectJ). In this case the hash code
133 will change and identity gets lost. On the other hand code coverage analysis
134 based on classes that have been somehow altered will produce unexpected
135 results. The CRC64 has code might produce so called <i>collisions</i>, i.e.
136 creating the same hash code for two different classes. Although CRC64 is not
137 cryptographically strong and collision examples can be easily computed, for
138 regular class files the collision probability is very low.
139</p>
140
141<h2>Coverage Runtime Dependency</h2>
142
143<p class="Note">
144 Instrumented code typically gets a dependency to coverage runtime data
145 structure. Making a runtime library available to all instrumented classes
146 can be a painful or impossible task in frameworks that use there own
147 class loading mechanisms. JaCoCo uses JRE types and interfaces only in
148 generated instrumentation code.
149</p>
150
151
152<hr/>
153<div style="float:right">@VERSION@</div>
154<div>Copyright &copy; 2009 Mountainminds GmbH &amp; Co. KG, Marc R. Hoffmann</div>
155
156</body>
157</html>