aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2018-08-06 16:50:35 -0700
committerXin Li <delphij@google.com>2018-08-06 16:50:35 -0700
commitc09ea2ab692393c0891eaefcca288ac3d19679b3 (patch)
treeda5a3f23c0349b599cb891415805eda15137f9af
parent730cc2668f7a8e9ef614b7bccf4b1586e77f9e90 (diff)
parent9da9e9d2228a0f37721df5749356f026a80a791f (diff)
downloadjacoco-c09ea2ab692393c0891eaefcca288ac3d19679b3.tar.gz
Merge Android Pie into masterandroid-o-mr1-iot-release-1.0.3
Bug: 112104996 Change-Id: Ife26a62a004cc7153634b9e2f6ca9a1c805a91a3
-rw-r--r--Android.mk2
-rw-r--r--README.android7
-rw-r--r--org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java4
-rw-r--r--org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java54
-rw-r--r--org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java58
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java5
-rw-r--r--org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java16
7 files changed, 130 insertions, 16 deletions
diff --git a/Android.mk b/Android.mk
index c708fc7f..a00938bb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,5 +17,5 @@ LOCAL_PATH := $(call my-dir)
# include jacoco-cli in the dist directory to enable running it to generate a code-coverage report
ifeq ($(EMMA_INSTRUMENT),true)
-$(call dist-for-goals, dist_files, $(HOST_OUT_JAVA_LIBRARIES)/jacoco-cli.jar)
+$(call dist-for-goals, dist_files apps_only, $(HOST_OUT_JAVA_LIBRARIES)/jacoco-cli.jar)
endif
diff --git a/README.android b/README.android
index cad30c6c..8fa2b902 100644
--- a/README.android
+++ b/README.android
@@ -14,3 +14,10 @@ is the list of the changes:
1) Remove the creation of JmxRegistration in org.jacoco.agent.rt.internal.Agent.
2) Change default OutputMode to none in org.jacoco.core.runtime.AgentOptions
+3) Change the runtime to reduce dependencies on core libraries.
+ Previously, Offline's static initializer would eagerly create an
+ Agent, a process which has lots of dependencies. With this change,
+ Offline only eagerly creates a Map<Long, ExecutionData>, which is much
+ more lightweight. The Agent is only created when it's actually
+ needed. This makes it possible to instrument a lot of more core
+ libraries without creating a circular dependency at runtime.
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java
index 45bc8bdc..9f9fc782 100644
--- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java
+++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java
@@ -37,6 +37,7 @@ import org.jacoco.core.runtime.AgentOptions.OutputMode;
import org.jacoco.core.runtime.RuntimeData;
import org.jacoco.core.tools.ExecFileLoader;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -132,6 +133,9 @@ public class AgentTest implements IExceptionLogger, IAgentOutput {
}
@Test
+ // BEGIN android-change
+ @Ignore
+ // END android-change
public void startup_should_register_mbean_when_enabled() throws Exception {
options.setJmx(true);
Agent agent = createAgent();
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
index 667a7d0f..b4dd0c10 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java
@@ -45,8 +45,26 @@ public class Agent implements IAgent {
* @return global instance
*/
public static synchronized Agent getInstance(final AgentOptions options) {
+ // BEGIN android-change
+ return getInstance(options, new RuntimeData());
+ // END android-change
+ }
+
+ // BEGIN android-change
+ /**
+ * Returns a global instance which is already started, reusing an existing set of runtime
+ * data. If the method is called the first time the instance is created with the given
+ * options.
+ *
+ * @param options
+ * options to configure the instance
+ * @param data
+ * the runtime data to reuse
+ * @return global instance
+ */
+ public static synchronized Agent getInstance(final AgentOptions options, RuntimeData data) {
if (singleton == null) {
- final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR);
+ final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR, data);
agent.startup();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
@@ -58,18 +76,26 @@ public class Agent implements IAgent {
}
return singleton;
}
+ // END android-change
+ // BEGIN android-change
/**
- * Returns a global instance which is already started. If a agent has not
- * been initialized before this method will fail.
+ * Returns a global instance which is already started. If an agent has not
+ * been initialized then one will be created via {@link Offline#createAgent()}.
+ * This will capture any data written via {@link Offline#getProbes} prior to
+ * this call, but not subsequently.
*
* @return global instance
* @throws IllegalStateException
* if no Agent has been started yet
*/
+ // END android-change
public static synchronized Agent getInstance() throws IllegalStateException {
if (singleton == null) {
- throw new IllegalStateException("JaCoCo agent not started.");
+ // BEGIN android-change
+ // throw new IllegalStateException("JaCoCo agent not started.");
+ singleton = Offline.createAgent();
+ // END android-change
}
return singleton;
}
@@ -93,10 +119,28 @@ public class Agent implements IAgent {
* logger used by this agent
*/
Agent(final AgentOptions options, final IExceptionLogger logger) {
+ // BEGIN android-change
+ this(options, logger, new RuntimeData());
+ // END android-change
+ }
+
+ // BEGIN android-change
+ /**
+ * Creates a new agent with the given agent options, reusing the given runtime data.
+ *
+ * @param options
+ * agent options
+ * @param logger
+ * logger used by this agent
+ * @param data
+ * the runtime data to reuse
+ */
+ private Agent(final AgentOptions options, final IExceptionLogger logger, RuntimeData data) {
this.options = options;
this.logger = logger;
- this.data = new RuntimeData();
+ this.data = data;
}
+ // END android-change
/**
* Returns the runtime data object created by this agent
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java
index 8b8b40c0..7eac19fa 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java
@@ -11,8 +11,12 @@
*******************************************************************************/
package org.jacoco.agent.rt.internal;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
+import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.runtime.AgentOptions;
import org.jacoco.core.runtime.RuntimeData;
@@ -22,14 +26,19 @@ import org.jacoco.core.runtime.RuntimeData;
*/
public final class Offline {
- private static final RuntimeData DATA;
+ // BEGIN android-change
+ // private static final RuntimeData DATA;
+ private static final Map<Long, ExecutionData> DATA = new HashMap<Long, ExecutionData>();
+ // END android-change
private static final String CONFIG_RESOURCE = "/jacoco-agent.properties";
- static {
- final Properties config = ConfigLoader.load(CONFIG_RESOURCE,
- System.getProperties());
- DATA = Agent.getInstance(new AgentOptions(config)).getData();
- }
+ // BEGIN android-change
+ // static {
+ // final Properties config = ConfigLoader.load(CONFIG_RESOURCE,
+ // System.getProperties());
+ // DATA = Agent.getInstance(new AgentOptions(config)).getData();
+ // }
+ // END android-change
private Offline() {
// no instances
@@ -48,8 +57,41 @@ public final class Offline {
*/
public static boolean[] getProbes(final long classid,
final String classname, final int probecount) {
- return DATA.getExecutionData(Long.valueOf(classid), classname,
- probecount).getProbes();
+ // BEGIN android-change
+ // return DATA.getExecutionData(Long.valueOf(classid), classname,
+ // probecount).getProbes();
+ synchronized (DATA) {
+ ExecutionData entry = DATA.get(classid);
+ if (entry == null) {
+ entry = new ExecutionData(classid, classname, probecount);
+ DATA.put(classid, entry);
+ } else {
+ entry.assertCompatibility(classid, classname, probecount);
+ }
+ return entry.getProbes();
+ }
+ // END android-change
}
+ // BEGIN android-change
+ /**
+ * Creates a default agent, using config loaded from the classpath resource and the system
+ * properties, and a runtime data instance populated with the execution data accumulated by
+ * the probes up until this call is made (subsequent probe updates will not be reflected in
+ * this agent).
+ *
+ * @return the new agent
+ */
+ static Agent createAgent() {
+ final Properties config = ConfigLoader.load(CONFIG_RESOURCE,
+ System.getProperties());
+ synchronized (DATA) {
+ ExecutionDataStore store = new ExecutionDataStore();
+ for (ExecutionData data : DATA.values()) {
+ store.put(data);
+ }
+ return Agent.getInstance(new AgentOptions(config), new RuntimeData(store));
+ }
+ }
+ // END android-change
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java
index f65142e9..155e3e88 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java
@@ -47,7 +47,10 @@ public class AgentOptionsTest {
assertFalse(options.getInclNoLocationClasses());
assertNull(options.getSessionId());
assertTrue(options.getDumpOnExit());
- assertEquals(AgentOptions.OutputMode.file, options.getOutput());
+ // BEGIN android-change
+ // assertEquals(AgentOptions.OutputMode.file, options.getOutput());
+ assertEquals(AgentOptions.OutputMode.none, options.getOutput());
+ // END android-change
assertEquals(AgentOptions.DEFAULT_ADDRESS, options.getAddress());
assertEquals(AgentOptions.DEFAULT_PORT, options.getPort());
assertNull(options.getClassDumpDir());
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
index ff249e73..74a51dcb 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
@@ -37,10 +37,24 @@ public class RuntimeData {
* Creates a new runtime.
*/
public RuntimeData() {
- store = new ExecutionDataStore();
+ // BEGIN android-change
+ this(new ExecutionDataStore());
+ // END android-change
+ }
+
+ // BEGIN android-change
+ /**
+ * Creates a new runtime, reusing an existing {@link ExecutionDataStore}.
+ *
+ * @param store
+ * the store to reuse
+ */
+ public RuntimeData(ExecutionDataStore store) {
+ this.store = store;
sessionId = "<none>";
startTimeStamp = System.currentTimeMillis();
}
+ // END android-change
/**
* Sets a session identifier for this runtime. The identifier is used when