From fea3a9fadc96adfd1e916f01a91a85fae159ac9b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Thu, 21 Dec 2017 14:19:38 +0100 Subject: [PATCH] Remove URLStreamHandlerRuntime * uses reflection to access internal members of the java.net.URL class * not used by default * has lower performance than ModifiedSystemClassRuntime that is used by default and than SystemPropertiesRuntime --- .../runtime/URLStreamHandlerRuntimeTest.java | 35 ---- .../core/runtime/URLStreamHandlerRuntime.java | 150 ------------------ org.jacoco.doc/docroot/doc/changes.html | 6 + .../docroot/doc/implementation.html | 6 - 4 files changed, 6 insertions(+), 191 deletions(-) delete mode 100644 org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java delete mode 100644 org.jacoco.core/src/org/jacoco/core/runtime/URLStreamHandlerRuntime.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java deleted file mode 100644 index 00155ffe6d..0000000000 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2020 Mountainminds GmbH & Co. KG and Contributors - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.core.runtime; - -import org.junit.Assume; -import org.junit.BeforeClass; - -/** - * Unit tests for {@link URLStreamHandlerRuntime}. - */ -public class URLStreamHandlerRuntimeTest extends RuntimeTestBase { - - @Override - IRuntime createRuntime() { - return new URLStreamHandlerRuntime(); - } - - @BeforeClass - public static void checkJDK() { - final boolean jdk9 = System.getProperty("java.version") - .startsWith("9-"); - Assume.assumeTrue(!jdk9); - } - -} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/URLStreamHandlerRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/URLStreamHandlerRuntime.java deleted file mode 100644 index a6fd147240..0000000000 --- a/org.jacoco.core/src/org/jacoco/core/runtime/URLStreamHandlerRuntime.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2020 Mountainminds GmbH & Co. KG and Contributors - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.core.runtime; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.Map; - -import org.jacoco.core.internal.instr.InstrSupport; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * This {@link IRuntime} implementation registers a special - * {@link URLStreamHandler} to process coverage data. The handler is not - * actually used for opening a URL, but to get access to the runtime object. - */ -public class URLStreamHandlerRuntime extends AbstractRuntime { - - private static final String PROTOCOLPREFIX = "jacoco-"; - - private final String protocol; - - private Map handlers; - - /** - * Creates a new runtime. - */ - public URLStreamHandlerRuntime() { - super(); - protocol = PROTOCOLPREFIX + Integer.toHexString(hashCode()); - } - - @Override - public void startup(final RuntimeData data) throws Exception { - super.startup(data); - handlers = getHandlersReference(); - handlers.put(protocol, handler); - } - - private Map getHandlersReference() - throws Exception { - final Field field = URL.class.getDeclaredField("handlers"); - field.setAccessible(true); - @SuppressWarnings("unchecked") - final Map map = (Map) field - .get(null); - return map; - } - - public void shutdown() { - handlers.remove(protocol); - } - - public int generateDataAccessor(final long classid, final String classname, - final int probecount, final MethodVisitor mv) { - - // The data accessor performs the following steps: - // - // final URL url = new URL(protocol, null, ""); - // final URLConnection connection = url.openConnection(); - // final Object[] args = new Object[3]; - // args[0] = Long.valueOf(classid); - // args[1] = classname; - // args[2] = Integer.valueOf(probecount); - // connection.equals(args); - // final byte[] probedata = (byte[]) args[0]; - - RuntimeData.generateArgumentArray(classid, classname, probecount, mv); - mv.visitInsn(Opcodes.DUP); - - // Stack[1]: [Ljava/lang/Object; - // Stack[0]: [Ljava/lang/Object; - - mv.visitTypeInsn(Opcodes.NEW, "java/net/URL"); - mv.visitInsn(Opcodes.DUP); - mv.visitLdcInsn(protocol); - mv.visitInsn(Opcodes.ACONST_NULL); - mv.visitLdcInsn(""); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/net/URL", "", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - false); - - // Stack[2]: [Ljava/net/URL; - // Stack[1]: [Ljava/lang/Object; - // Stack[0]: [Ljava/lang/Object; - - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/net/URL", - "openConnection", "()Ljava/net/URLConnection;", false); - - // Stack[2]: [Ljava/net/URLConnection; - // Stack[1]: [Ljava/lang/Object; - // Stack[0]: [Ljava/lang/Object; - - mv.visitInsn(Opcodes.SWAP); - - // Stack[2]: [Ljava/lang/Object; - // Stack[1]: [Ljava/net/URLConnection; - // Stack[0]: [Ljava/lang/Object; - - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", - "(Ljava/lang/Object;)Z", false); - - // Stack[1]: Z; - // Stack[0]: [Ljava/lang/Object; - - mv.visitInsn(Opcodes.POP); - - // Stack[0]: [Ljava/lang/Object; - - mv.visitInsn(Opcodes.ICONST_0); - mv.visitInsn(Opcodes.AALOAD); - mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC); - - return 7; - } - - private final URLStreamHandler handler = new URLStreamHandler() { - @Override - protected URLConnection openConnection(final URL u) throws IOException { - return connection; - } - }; - - private final URLConnection connection = new URLConnection(null) { - @Override - public void connect() throws IOException { - throw new AssertionError(); - } - - @Override - public boolean equals(final Object obj) { - return data.equals(obj); - } - }; - -} diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index aaa783e835..87bcbee9f7 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -54,6 +54,12 @@

Non-functional Changes

(GitHub #1032). +

API Changes

+
    +
  • URLStreamHandlerRuntime removed + (GitHub #471).
  • +
+

Release 0.8.5 (2019/10/11)

New Features

diff --git a/org.jacoco.doc/docroot/doc/implementation.html b/org.jacoco.doc/docroot/doc/implementation.html index 2a11f7562c..fda79e6f71 100644 --- a/org.jacoco.doc/docroot/doc/implementation.html +++ b/org.jacoco.doc/docroot/doc/implementation.html @@ -200,12 +200,6 @@

Coverage Runtime Dependency

runtime registers a custom Handler to receive the parameter array. This approach might break environments that install their own log managers (e.g. Glassfish). -
  • URLStreamHandlerRuntime: This runtime registers a - URLStreamHandler for a "jacoco-xxxxx" protocol. Instrumented - classes open a connection on this protocol. The returned connection object - is the one that provides access to the coverage runtime through its - equals() method. However to register the protocol the runtime - needs to access internal members of the java.net.URL class.
  • ModifiedSystemClassRuntime: This approach adds a public static field to an existing JRE class through instrumentation. Unlike the other methods above this is only possible for environments where a Java