JacocoAgent.java
1/*******************************************************************************
2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
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 * $Id: $
12 *******************************************************************************/
13package org.jacoco.agent.rt;
14
15import java.io.BufferedOutputStream;
16import java.io.File;
17import java.io.FileOutputStream;
18import java.io.IOException;
19import java.io.OutputStream;
20import java.lang.instrument.Instrumentation;
21
22import org.jacoco.core.data.ExecutionDataWriter;
23import org.jacoco.core.runtime.AgentOptions;
24import org.jacoco.core.runtime.IRuntime;
25import org.jacoco.core.runtime.LoggerRuntime;
26
27/**
28 * The agent which is referred as the <code>Premain-Class</code>.
29 *
30 * @author Marc R. Hoffmann
31 * @version $Revision: $
32 */
33public class JacocoAgent {
34
35 private final AgentOptions options;
36
37 private IRuntime runtime;
38
39 /**
40 * Creates a new agent with the given agent options.
41 *
42 * @param options
43 * agent options
44 */
45 public JacocoAgent(AgentOptions options) {
46 this.options = options;
47 }
48
49 /**
50 * Creates a new agent with the given agent options string.
51 *
52 * @param agentArgs
53 * agent options as text string
54 */
55 public JacocoAgent(String options) {
56 this(new AgentOptions(options));
57 }
58
59 /**
60 * Initializes this agent.
61 *
62 * @param inst
63 * instrumentation callback
64 */
65 public void init(final Instrumentation inst) {
66 runtime = createRuntime();
67 runtime.startup();
68 inst.addTransformer(new CoverageTransformer(runtime, options));
69 }
70
71 /**
72 * Creates the specific coverage runtime implementation.
73 *
74 * @return coverage runtime instance
75 */
76 protected IRuntime createRuntime() {
77 return new LoggerRuntime();
78 }
79
80 /**
81 * Shutdown the agent again.
82 */
83 public void shutdown() {
84 writeExecutionData();
85 }
86
87 /**
88 * Writes the collected execution data to the specified file.
89 *
90 * @param runtime
91 * runtime containing the execution data
92 */
93 protected void writeExecutionData() {
94 try {
95 File execFile = new File(options.getFile()).getAbsoluteFile();
96 File folder = execFile.getParentFile();
97 if (folder != null) {
98 folder.mkdirs();
99 }
100 OutputStream output = new BufferedOutputStream(
101 new FileOutputStream(execFile, options.getMerge()));
102 ExecutionDataWriter writer = new ExecutionDataWriter(output);
103 writer.writeHeader();
104 runtime.collect(writer, false);
105 output.close();
106 } catch (IOException e) {
107 e.printStackTrace();
108 }
109 }
110
111 /**
112 * This method is called by the JVM to initialize Java agents.
113 *
114 * @param options
115 * agent options
116 * @param inst
117 * intrumentation callback provided by the JVM
118 */
119 public static void premain(final String options, final Instrumentation inst) {
120 final JacocoAgent agent = new JacocoAgent(options);
121 agent.init(inst);
122
123 Runtime.getRuntime().addShutdownHook(new Thread() {
124 @Override
125 public void run() {
126 agent.shutdown();
127 }
128 });
129 }
130
131}