1 /******************************************************************************* 2 * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.agent; 13 14 import java.io.Closeable; 15 import java.io.File; 16 import java.io.FileOutputStream; 17 import java.io.IOException; 18 import java.io.InputStream; 19 import java.io.OutputStream; 20 import java.net.URL; 21 22 /** 23 * API to access the agent JAR file as a resource. While the agent is a JAR file 24 * it is considered as a plain resource that must be configured for the 25 * application under test (target JVM). The agent JAR does not provide any 26 * public Java API. 27 */ 28 public final class AgentJar { 29 30 /** 31 * Name of the agent JAR file resource within this bundle. 32 */ 33 private static final String RESOURCE = "/jacocoagent.jar"; 34 AgentJar()35 private AgentJar() { 36 } 37 38 /** 39 * Returns a URL pointing to the JAR file. 40 * 41 * @return URL of the JAR file 42 */ getResource()43 public static URL getResource() { 44 final URL url = AgentJar.class.getResource(RESOURCE); 45 if (url == null) { 46 throw new AssertionError(ERRORMSG); 47 } 48 return url; 49 } 50 51 /** 52 * Returns the content of the JAR file as a stream. 53 * 54 * @return content of the JAR file 55 */ getResourceAsStream()56 public static InputStream getResourceAsStream() { 57 final InputStream stream = AgentJar.class.getResourceAsStream(RESOURCE); 58 if (stream == null) { 59 throw new AssertionError(ERRORMSG); 60 } 61 return stream; 62 } 63 64 /** 65 * Extract the JaCoCo agent JAR and put it into a temporary location. This 66 * file should be deleted on exit, but may not if the VM is terminated 67 * 68 * @return Location of the Agent Jar file in the local file system. The file 69 * should exist and be readable. 70 * @throws IOException 71 * Unable to unpack agent jar 72 */ extractToTempLocation()73 public static File extractToTempLocation() throws IOException { 74 final File agentJar = File.createTempFile("jacocoagent", ".jar"); 75 agentJar.deleteOnExit(); 76 77 extractTo(agentJar); 78 79 return agentJar; 80 } 81 82 /** 83 * Extract the JaCoCo agent JAR and put it into the specified location. 84 * 85 * @param destination 86 * Location to write JaCoCo Agent Jar to. Must be writeable 87 * @throws IOException 88 * Unable to unpack agent jar 89 */ extractTo(File destination)90 public static void extractTo(File destination) throws IOException { 91 InputStream inputJarStream = getResourceAsStream(); 92 OutputStream outputJarStream = null; 93 94 try { 95 96 outputJarStream = new FileOutputStream(destination); 97 98 final byte[] buffer = new byte[8192]; 99 100 int bytesRead; 101 while ((bytesRead = inputJarStream.read(buffer)) != -1) { 102 outputJarStream.write(buffer, 0, bytesRead); 103 } 104 } finally { 105 safeClose(inputJarStream); 106 safeClose(outputJarStream); 107 } 108 } 109 110 /** 111 * Close a stream ignoring any error 112 * 113 * @param closeable 114 * stream to be closed 115 */ safeClose(Closeable closeable)116 private static void safeClose(Closeable closeable) { 117 try { 118 if (closeable != null) { 119 closeable.close(); 120 } 121 } catch (IOException e) { 122 } 123 } 124 125 private static final String ERRORMSG = String.format( 126 "The resource %s has not been found. Please see " 127 + "/org.jacoco.agent/README.TXT for details.", RESOURCE); 128 129 } 130