aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.agent.rt
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2012-12-23 10:09:46 +0100
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2012-12-23 10:10:35 +0100
commit25fb3d4e2bac150627f091d310bafb6be465f37b (patch)
tree99a1b5da92484b3f58eb250e3e18074093bd6aca /org.jacoco.agent.rt
parent27e32e433ba0ac1fdec9290d3454d5b369c969cc (diff)
downloadjacoco-25fb3d4e2bac150627f091d310bafb6be465f37b.tar.gz
Offline instrumentation APIs.
Diffstat (limited to 'org.jacoco.agent.rt')
-rw-r--r--org.jacoco.agent.rt/pom.xml28
-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.java9
-rw-r--r--org.jacoco.agent.rt/src/org/jacoco/agent/rt/PreMain.java54
-rw-r--r--org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java52
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();
+ }
+
+}