• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *    Evgeny Mandrikov - initial API and implementation
10  *
11  *******************************************************************************/
12 package org.jacoco.core.test;
13 
14 import java.io.IOException;
15 
16 import org.jacoco.core.data.ExecutionDataStore;
17 import org.jacoco.core.data.SessionInfoStore;
18 import org.jacoco.core.instr.Instrumenter;
19 import org.jacoco.core.runtime.IRuntime;
20 import org.jacoco.core.runtime.RuntimeData;
21 import org.jacoco.core.runtime.SystemPropertiesRuntime;
22 
23 /**
24  * Class loader which loads classes from another class loader and instruments
25  * them.
26  */
27 public final class InstrumentingLoader extends ClassLoader {
28 
29 	private final IRuntime runtime;
30 	private final String scope;
31 	private final ClassLoader delegate;
32 
33 	private final RuntimeData data;
34 	private final Instrumenter instrumenter;
35 
InstrumentingLoader(IRuntime runtime, String scope, ClassLoader delegate)36 	public InstrumentingLoader(IRuntime runtime, String scope,
37 			ClassLoader delegate) throws Exception {
38 		this.runtime = runtime;
39 		this.scope = scope;
40 		this.delegate = delegate;
41 		this.data = new RuntimeData();
42 		runtime.startup(data);
43 		this.instrumenter = new Instrumenter(runtime);
44 	}
45 
InstrumentingLoader(Class<?> target)46 	public InstrumentingLoader(Class<?> target) throws Exception {
47 		this(new SystemPropertiesRuntime(), target.getPackage().getName(),
48 				target.getClassLoader());
49 	}
50 
51 	@Override
loadClass(String name, boolean resolve)52 	protected synchronized Class<?> loadClass(String name, boolean resolve)
53 			throws ClassNotFoundException {
54 		if (name.startsWith(scope)) {
55 			final byte[] bytes;
56 			try {
57 				bytes = TargetLoader.getClassDataAsBytes(delegate, name);
58 			} catch (IOException e) {
59 				throw new ClassNotFoundException("Unable to load", e);
60 			}
61 			final byte[] instrumented;
62 			try {
63 				instrumented = instrumenter.instrument(bytes, name);
64 			} catch (IOException e) {
65 				throw new ClassNotFoundException("Unable to instrument", e);
66 			}
67 			final Class<?> c = defineClass(name, instrumented, 0,
68 					instrumented.length);
69 			if (resolve) {
70 				resolveClass(c);
71 			}
72 			return c;
73 		}
74 		return super.loadClass(name, resolve);
75 	}
76 
collect()77 	public ExecutionDataStore collect() {
78 		final ExecutionDataStore store = new ExecutionDataStore();
79 		data.collect(store, new SessionInfoStore(), false);
80 		runtime.shutdown();
81 		return store;
82 	}
83 
84 }
85