diff options
author | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2012-12-23 10:09:46 +0100 |
---|---|---|
committer | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2012-12-23 10:10:35 +0100 |
commit | 25fb3d4e2bac150627f091d310bafb6be465f37b (patch) | |
tree | 99a1b5da92484b3f58eb250e3e18074093bd6aca /org.jacoco.agent.rt | |
parent | 27e32e433ba0ac1fdec9290d3454d5b369c969cc (diff) | |
download | jacoco-25fb3d4e2bac150627f091d310bafb6be465f37b.tar.gz |
Offline instrumentation APIs.
Diffstat (limited to 'org.jacoco.agent.rt')
-rw-r--r-- | org.jacoco.agent.rt/pom.xml | 28 | ||||
-rw-r--r-- | org.jacoco.agent.rt/src/org/jacoco/agent/rt/Agent.java (renamed from org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java) | 133 | ||||
-rw-r--r-- | org.jacoco.agent.rt/src/org/jacoco/agent/rt/IExceptionLogger.java | 9 | ||||
-rw-r--r-- | org.jacoco.agent.rt/src/org/jacoco/agent/rt/PreMain.java | 54 | ||||
-rw-r--r-- | org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java | 52 |
5 files changed, 173 insertions, 103 deletions
diff --git a/org.jacoco.agent.rt/pom.xml b/org.jacoco.agent.rt/pom.xml index fa0c2831..bcf06294 100644 --- a/org.jacoco.agent.rt/pom.xml +++ b/org.jacoco.agent.rt/pom.xml @@ -42,26 +42,6 @@ <sourceDirectory>src</sourceDirectory> <plugins> - <!-- Generates random number for relocation of packages --> - <plugin> - <groupId>org.codehaus.groovy.maven</groupId> - <artifactId>gmaven-plugin</artifactId> - <executions> - <execution> - <phase>validate</phase> - <goals> - <goal>execute</goal> - </goals> - <configuration> - <source> - def id = Math.abs(new java.util.Random().nextInt()) - project.properties['rt'] = "rt_" + Integer.toString(id, Character.MAX_RADIX) - </source> - </configuration> - </execution> - </executions> - </plugin> - <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> @@ -78,21 +58,21 @@ <relocations> <relocation> <pattern>org.jacoco.agent.rt</pattern> - <shadedPattern>org.jacoco.agent.${rt}</shadedPattern> + <shadedPattern>${jacoco.runtime.package.name}</shadedPattern> </relocation> <relocation> <pattern>org.jacoco.core</pattern> - <shadedPattern>org.jacoco.agent.${rt}.core</shadedPattern> + <shadedPattern>${jacoco.runtime.package.name}.core</shadedPattern> </relocation> <relocation> <pattern>org.objectweb.asm</pattern> - <shadedPattern>org.jacoco.agent.${rt}.asm</shadedPattern> + <shadedPattern>${jacoco.runtime.package.name}.asm</shadedPattern> </relocation> </relocations> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> - <Premain-Class>org.jacoco.agent.${rt}.JacocoAgent</Premain-Class> + <Premain-Class>${jacoco.runtime.package.name}.PreMain</Premain-Class> </manifestEntries> </transformer> </transformers> diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/Agent.java index 1f858b5c..67ccdccc 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/Agent.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.jacoco.agent.rt; -import java.lang.instrument.Instrumentation; import java.net.InetAddress; import java.net.UnknownHostException; @@ -23,14 +22,40 @@ import org.jacoco.agent.rt.controller.TcpServerController; import org.jacoco.core.runtime.AbstractRuntime; import org.jacoco.core.runtime.AgentOptions; import org.jacoco.core.runtime.AgentOptions.OutputMode; -import org.jacoco.core.runtime.IRuntime; -import org.jacoco.core.runtime.ModifiedSystemClassRuntime; import org.jacoco.core.runtime.RuntimeData; /** - * The agent which is referred as the <code>Premain-Class</code>. + * The agent manages the life cycle of JaCoCo runtime. */ -public class JacocoAgent { +public class Agent { + + private static Agent singleton; + + /** + * Returns a global instance which is already started. If the method is + * called the first time the instance is created with the given options. + * + * @param options + * options to configure the instance + * @return global instance + * @throws Exception + * in case of startup failures of the corresponding controller + */ + public static synchronized Agent getInstance(final AgentOptions options) + throws Exception { + if (singleton == null) { + final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR); + agent.startup(); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + agent.shutdown(); + } + }); + singleton = agent; + } + return singleton; + } private final AgentOptions options; @@ -38,6 +63,8 @@ public class JacocoAgent { private IAgentController controller; + private final RuntimeData data; + /** * Creates a new agent with the given agent options. * @@ -46,51 +73,57 @@ public class JacocoAgent { * @param logger * logger used by this agent */ - public JacocoAgent(final AgentOptions options, final IExceptionLogger logger) { + public Agent(final AgentOptions options, final IExceptionLogger logger) { this.options = options; this.logger = logger; + this.data = new RuntimeData(); } /** - * Creates a new agent with the given agent options string. + * Returns the runtime data object created by this agent * - * @param options - * agent options as text string - * @param logger - * logger used by this agent + * @return runtime data for this agent instance */ - public JacocoAgent(final String options, final IExceptionLogger logger) { - this(new AgentOptions(options), logger); + public RuntimeData getData() { + return data; } /** * Initializes this agent. * - * @param inst - * instrumentation services * @throws Exception * internal startup problem */ - public void init(final Instrumentation inst) throws Exception { - final IRuntime runtime = createRuntime(inst); - final RuntimeData data = new RuntimeData(); + public void startup() throws Exception { String sessionId = options.getSessionId(); if (sessionId == null) { sessionId = createSessionId(); } data.setSessionId(sessionId); - runtime.startup(data); - inst.addTransformer(new CoverageTransformer(runtime, options, logger)); controller = createAgentController(); controller.startup(options, data); } /** + * Shutdown the agent again. + */ + public void shutdown() { + try { + if (options.getDumpOnExit()) { + controller.writeExecutionData(); + } + controller.shutdown(); + } catch (final Exception e) { + logger.logExeption(e); + } + } + + /** * Create controller implementation as given by the agent options. * * @return configured controller implementation */ - protected IAgentController createAgentController() { + IAgentController createAgentController() { final OutputMode controllerType = options.getOutput(); switch (controllerType) { case file: @@ -116,62 +149,4 @@ public class JacocoAgent { return host + "-" + AbstractRuntime.createRandomId(); } - /** - * Creates the specific coverage runtime implementation. - * - * @param inst - * instrumentation services - * @return coverage runtime instance - * @throws Exception - * creation problem - */ - protected IRuntime createRuntime(final Instrumentation inst) - throws Exception { - return ModifiedSystemClassRuntime.createFor(inst, "java/util/UUID"); - } - - /** - * Shutdown the agent again. - */ - public void shutdown() { - try { - if (options.getDumpOnExit()) { - controller.writeExecutionData(); - } - controller.shutdown(); - } catch (final Exception e) { - logger.logExeption(e); - } - } - - /** - * This method is called by the JVM to initialize Java agents. - * - * @param options - * agent options - * @param inst - * instrumentation callback provided by the JVM - * @throws Exception - * in case initialization fails - */ - public static void premain(final String options, final Instrumentation inst) - throws Exception { - - final JacocoAgent agent = new JacocoAgent(options, - new IExceptionLogger() { - public void logExeption(final Exception ex) { - ex.printStackTrace(); - } - }); - - agent.init(inst); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - agent.shutdown(); - } - }); - } - } diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/IExceptionLogger.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/IExceptionLogger.java index 6c7da4eb..8aa7c548 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/IExceptionLogger.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/IExceptionLogger.java @@ -18,6 +18,15 @@ package org.jacoco.agent.rt; public interface IExceptionLogger { /** + * Default implementation which dumps the stack trace to System.err. + */ + IExceptionLogger SYSTEM_ERR = new IExceptionLogger() { + public void logExeption(final Exception ex) { + ex.printStackTrace(); + } + }; + + /** * Logs the given exception. * * @param ex diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/PreMain.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/PreMain.java new file mode 100644 index 00000000..f6822147 --- /dev/null +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/PreMain.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import java.lang.instrument.Instrumentation; + +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.ModifiedSystemClassRuntime; + +/** + * The agent which is referred as the <code>Premain-Class</code>. The agent + * configuration is provided with the agent parameters in the command line. + */ +public class PreMain { + + /** + * This method is called by the JVM to initialize Java agents. + * + * @param options + * agent options + * @param inst + * instrumentation callback provided by the JVM + * @throws Exception + * in case initialization fails + */ + public static void premain(final String options, final Instrumentation inst) + throws Exception { + + final AgentOptions agentOptions = new AgentOptions(options); + + final Agent agent = Agent.getInstance(agentOptions); + + final IRuntime runtime = createRuntime(inst); + runtime.startup(agent.getData()); + inst.addTransformer(new CoverageTransformer(runtime, agentOptions, + IExceptionLogger.SYSTEM_ERR)); + } + + private static IRuntime createRuntime(final Instrumentation inst) + throws Exception { + return ModifiedSystemClassRuntime.createFor(inst, "java/util/UUID"); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java new file mode 100644 index 00000000..87bbc190 --- /dev/null +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RuntimeData; + +/** + * The API for classes instrumented in "offline" mode. The agent configuration + * is provided through system properties prefixed with <code>jacoco.</code>. + */ +public class RT { + + private static final RuntimeData data; + + static { + try { + final Agent agent = Agent.getInstance(new AgentOptions( + System.getProperties())); + data = agent.getData(); + } catch (final Exception e) { + throw new RuntimeException("Error while creating JaCoCo Runtime", e); + } + } + + /** + * API for offline instrumented classes. + * + * @param classid + * class identifier + * @param classname + * VM class name + * @param probecount + * probe count for this class + * @return probe array instance for this class + */ + public static boolean[] getProbes(final long classid, + final String classname, final int probecount) { + return data.getExecutionData(Long.valueOf(classid), classname, + probecount).getProbes(); + } + +} |