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