blob: 1e4c6efe8473ec8f6fde4ce320b8d3a495deb69f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.attach.spi;
27
28import java.io.IOException;
29import java.util.Collections;
30import java.util.Iterator;
31import java.util.ArrayList;
32import java.util.List;
33import com.sun.tools.attach.VirtualMachine;
34import com.sun.tools.attach.VirtualMachineDescriptor;
35import com.sun.tools.attach.AttachPermission;
36import com.sun.tools.attach.AttachNotSupportedException;
37import java.util.ServiceLoader;
38
39/**
40 * Attach provider class for attaching to a Java virtual machine.
41 *
42 * <p> An attach provider is a concrete subclass of this class that has a
43 * zero-argument constructor and implements the abstract methods specified
44 * below. </p>
45 *
46 * <p> An attach provider implementation is typically tied to a Java virtual
47 * machine implementation, version, or even mode of operation. That is, a specific
48 * provider implementation will typically only be capable of attaching to
49 * a specific Java virtual machine implementation or version. For example, Sun's
50 * JDK implementation ships with provider implementations that can only attach to
51 * Sun's <i>HotSpot</i> virtual machine. In general, if an environment
52 * consists of Java virtual machines of different versions and from different
53 * vendors then there will be an attach provider implementation for each
54 * <i>family</i> of implementations or versions. </p>
55 *
56 * <p> An attach provider is identified by its {@link #name <i>name</i>} and
57 * {@link #type <i>type</i>}. The <i>name</i> is typically, but not required to
58 * be, a name that corresponds to the VM vendor. The Sun JDK implementation,
59 * for example, ships with attach providers that use the name <i>"sun"</i>. The
60 * <i>type</i> typically corresponds to the attach mechanism. For example, an
61 * implementation that uses the Doors inter-process communication mechanism
62 * might use the type <i>"doors"</i>. The purpose of the name and type is to
63 * identify providers in environments where there are multiple providers
64 * installed. </p>
65 *
66 * <p> AttachProvider implementations are loaded and instantiated at the first
67 * invocation of the {@link #providers() providers} method. This method
68 * attempts to load all provider implementations that are installed on the
69 * platform. </p>
70 *
71 * <p> All of the methods in this class are safe for use by multiple
72 * concurrent threads. </p>
73 *
74 * @since 1.6
75 */
76
77public abstract class AttachProvider {
78
79 private static final Object lock = new Object();
80 private static List<AttachProvider> providers = null;
81
82 /**
83 * Initializes a new instance of this class. </p>
84 *
85 * @throws SecurityException
86 * If a security manager has been installed and it denies
87 * {@link com.sun.tools.attach.AttachPermission AttachPermission}
88 * <tt>("createAttachProvider")</tt>
89 */
90 protected AttachProvider() {
91 SecurityManager sm = System.getSecurityManager();
92 if (sm != null)
93 sm.checkPermission(new AttachPermission("createAttachProvider"));
94 }
95
96 /**
97 * Return this provider's name. </p>
98 *
99 * @return The name of this provider
100 */
101 public abstract String name();
102
103 /**
104 * Return this provider's type. </p>
105 *
106 * @return The type of this provider
107 */
108 public abstract String type();
109
110 /**
111 * Attaches to a Java virtual machine.
112 *
113 * <p> A Java virtual machine is identified by an abstract identifier. The
114 * nature of this identifier is platform dependent but in many cases it will be the
115 * string representation of the process identifier (or pid). </p>
116 *
117 * <p> This method parses the identifier and maps the identifier to a Java
118 * virtual machine (in an implementation dependent manner). If the identifier
119 * cannot be parsed by the provider then an {@link
120 * com.sun.tools.attach.AttachNotSupportedException AttachNotSupportedException}
121 * is thrown. Once parsed this method attempts to attach to the Java virtual machine.
122 * If the provider detects that the identifier corresponds to a Java virtual machine
123 * that does not exist, or it corresponds to a Java virtual machine that does not support
124 * the attach mechanism implemented by this provider, or it detects that the
125 * Java virtual machine is a version to which this provider cannot attach, then
126 * an <code>AttachNotSupportedException</code> is thrown. </p>
127 *
128 * @param id
129 * The abstract identifier that identifies the Java virtual machine.
130 *
131 * @return VirtualMachine representing the target virtual machine.
132 *
133 * @throws SecurityException
134 * If a security manager has been installed and it denies
135 * {@link com.sun.tools.attach.AttachPermission AttachPermission}
136 * <tt>("attachVirtualMachine")</tt>, or other permission
137 * required by the implementation.
138 *
139 * @throws AttachNotSupportedException
140 * If the identifier cannot be parsed, or it corresponds to
141 * to a Java virtual machine that does not exist, or it
142 * corresponds to a Java virtual machine which this
143 * provider cannot attach.
144 *
145 * @throws IOException
146 * If some other I/O error occurs
147 *
148 * @throws NullPointerException
149 * If <code>id</code> is <code>null</code>
150 */
151 public abstract VirtualMachine attachVirtualMachine(String id)
152 throws AttachNotSupportedException, IOException;
153
154 /**
155 * Attaches to a Java virtual machine.
156 *
157 * <p> A Java virtual machine can be described using a {@link
158 * com.sun.tools.attach.VirtualMachineDescriptor VirtualMachineDescriptor}.
159 * This method invokes the descriptor's {@link
160 * com.sun.tools.attach.VirtualMachineDescriptor#provider() provider()} method
161 * to check that it is equal to this provider. It then attempts to attach to the
162 * Java virtual machine.
163 *
164 * @param vmd
165 * The virtual machine descriptor
166 *
167 * @return VirtualMachine representing the target virtual machine.
168 *
169 * @throws SecurityException
170 * If a security manager has been installed and it denies
171 * {@link com.sun.tools.attach.AttachPermission AttachPermission}
172 * <tt>("attachVirtualMachine")</tt>, or other permission
173 * required by the implementation.
174 *
175 * @throws AttachNotSupportedException
176 * If the descriptor's {@link
177 * com.sun.tools.attach.VirtualMachineDescriptor#provider() provider()} method
178 * returns a provider that is not this provider, or it does not correspond
179 * to a Java virtual machine to which this provider can attach.
180 *
181 * @throws IOException
182 * If some other I/O error occurs
183 *
184 * @throws NullPointerException
185 * If <code>vmd</code> is <code>null</code>
186 */
187 public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd)
188 throws AttachNotSupportedException, IOException
189 {
190 if (vmd.provider() != this) {
191 throw new AttachNotSupportedException("provider mismatch");
192 }
193 return attachVirtualMachine(vmd.id());
194 }
195
196 /**
197 * Lists the Java virtual machines known to this provider.
198 *
199 * <p> This method returns a list of {@link
200 * com.sun.tools.attach.VirtualMachineDescriptor} elements. Each
201 * <code>VirtualMachineDescriptor</code> describes a Java virtual machine
202 * to which this provider can <i>potentially</i> attach. There isn't any
203 * guarantee that invoking {@link #attachVirtualMachine(VirtualMachineDescriptor)
204 * attachVirtualMachine} on each descriptor in the list will succeed.
205 *
206 * @return The list of virtual machine descriptors which describe the
207 * Java virtual machines known to this provider (may be empty).
208 */
209 public abstract List<VirtualMachineDescriptor> listVirtualMachines();
210
211
212 /**
213 * Returns a list of the installed attach providers.
214 *
215 * <p> An AttachProvider is installed on the platform if:
216 *
217 * <ul>
218 * <li><p>It is installed in a JAR file that is visible to the defining
219 * class loader of the AttachProvider type (usually, but not required
220 * to be, the {@link java.lang.ClassLoader#getSystemClassLoader system
221 * class loader}).</p></li>
222 *
223 * <li><p>The JAR file contains a provider configuration named
224 * <tt>com.sun.tools.attach.spi.AttachProvider</tt> in the resource directory
225 * <tt>META-INF/services</tt>. </p></li>
226 *
227 * <li><p>The provider configuration file lists the full-qualified class
228 * name of the AttachProvider implementation. </p></li>
229 * </ul>
230 *
231 * <p> The format of the provider configuration file is one fully-qualified
232 * class name per line. Space and tab characters surrounding each class name,
233 * as well as blank lines are ignored. The comment character is
234 * <tt>'#'</tt> (<tt>0x23</tt>), and on each line all characters following
235 * the first comment character are ignored. The file must be encoded in
236 * UTF-8. </p>
237 *
238 * <p> AttachProvider implementations are loaded and instantiated
239 * (using the zero-arg constructor) at the first invocation of this method.
240 * The list returned by the first invocation of this method is the list
241 * of providers. Subsequent invocations of this method return a list of the same
242 * providers. The list is unmodifable.</p>
243 *
244 * @return A list of the installed attach providers.
245 */
246 public static List<AttachProvider> providers() {
247 synchronized (lock) {
248 if (providers == null) {
249 providers = new ArrayList<AttachProvider>();
250
251 ServiceLoader<AttachProvider> providerLoader =
252 ServiceLoader.load(AttachProvider.class,
253 AttachProvider.class.getClassLoader());
254
255 Iterator<AttachProvider> i = providerLoader.iterator();
256
257 while (i.hasNext()) {
258 try {
259 providers.add(i.next());
260 } catch (Throwable t) {
261 if (t instanceof ThreadDeath) {
262 ThreadDeath td = (ThreadDeath)t;
263 throw td;
264 }
265 // Ignore errors and exceptions
266 System.err.println(t);
267 }
268 }
269 }
270 return Collections.unmodifiableList(providers);
271 }
272 }
273}