/******************************************************************************* * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Evgeny Mandrikov - initial API and implementation * *******************************************************************************/ package org.jacoco.core.test; import java.io.IOException; import org.jacoco.core.data.ExecutionDataStore; import org.jacoco.core.data.SessionInfoStore; import org.jacoco.core.instr.Instrumenter; import org.jacoco.core.runtime.IRuntime; import org.jacoco.core.runtime.RuntimeData; import org.jacoco.core.runtime.SystemPropertiesRuntime; /** * Class loader which loads classes from another class loader and instruments * them. */ public final class InstrumentingLoader extends ClassLoader { private final IRuntime runtime; private final String scope; private final ClassLoader delegate; private final RuntimeData data; private final Instrumenter instrumenter; public InstrumentingLoader(IRuntime runtime, String scope, ClassLoader delegate) throws Exception { this.runtime = runtime; this.scope = scope; this.delegate = delegate; this.data = new RuntimeData(); runtime.startup(data); this.instrumenter = new Instrumenter(runtime); } public InstrumentingLoader(Class<?> target) throws Exception { this(new SystemPropertiesRuntime(), target.getPackage().getName(), target.getClassLoader()); } @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (name.startsWith(scope)) { final byte[] bytes; try { bytes = TargetLoader.getClassDataAsBytes(delegate, name); } catch (IOException e) { throw new ClassNotFoundException("Unable to load", e); } final byte[] instrumented; try { instrumented = instrumenter.instrument(bytes, name); } catch (IOException e) { throw new ClassNotFoundException("Unable to instrument", e); } final Class<?> c = defineClass(name, instrumented, 0, instrumented.length); if (resolve) { resolveClass(c); } return c; } return super.loadClass(name, resolve); } public ExecutionDataStore collect() { final ExecutionDataStore store = new ExecutionDataStore(); data.collect(store, new SessionInfoStore(), false); runtime.shutdown(); return store; } }