1 /* 2 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.attach.spi; 27 28 import java.io.IOException; 29 import java.util.Collections; 30 import java.util.Iterator; 31 import java.util.ArrayList; 32 import java.util.List; 33 import com.sun.tools.attach.VirtualMachine; 34 import com.sun.tools.attach.VirtualMachineDescriptor; 35 import com.sun.tools.attach.AttachPermission; 36 import com.sun.tools.attach.AttachNotSupportedException; 37 import 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 77 @jdk.Supported 78 public abstract class AttachProvider { 79 80 private static final Object lock = new Object(); 81 private static List<AttachProvider> providers = null; 82 83 /** 84 * Initializes a new instance of this class. </p> 85 * 86 * @throws SecurityException 87 * If a security manager has been installed and it denies 88 * {@link com.sun.tools.attach.AttachPermission AttachPermission} 89 * <tt>("createAttachProvider")</tt> 90 */ 91 protected AttachProvider() { 92 SecurityManager sm = System.getSecurityManager(); 93 if (sm != null) 94 sm.checkPermission(new AttachPermission("createAttachProvider")); 95 } 96 97 /** 98 * Return this provider's name. </p> 99 * 100 * @return The name of this provider 101 */ 102 public abstract String name(); 103 104 /** 105 * Return this provider's type. </p> 106 * 107 * @return The type of this provider 108 */ 109 public abstract String type(); 110 111 /** 112 * Attaches to a Java virtual machine. 113 * 114 * <p> A Java virtual machine is identified by an abstract identifier. The 115 * nature of this identifier is platform dependent but in many cases it will be the 116 * string representation of the process identifier (or pid). </p> 117 * 118 * <p> This method parses the identifier and maps the identifier to a Java 119 * virtual machine (in an implementation dependent manner). If the identifier 120 * cannot be parsed by the provider then an {@link 121 * com.sun.tools.attach.AttachNotSupportedException AttachNotSupportedException} 122 * is thrown. Once parsed this method attempts to attach to the Java virtual machine. 123 * If the provider detects that the identifier corresponds to a Java virtual machine 124 * that does not exist, or it corresponds to a Java virtual machine that does not support 125 * the attach mechanism implemented by this provider, or it detects that the 126 * Java virtual machine is a version to which this provider cannot attach, then 127 * an <code>AttachNotSupportedException</code> is thrown. </p> 128 * 129 * @param id 130 * The abstract identifier that identifies the Java virtual machine. 131 * 132 * @return VirtualMachine representing the target virtual machine. 133 * 134 * @throws SecurityException 135 * If a security manager has been installed and it denies 136 * {@link com.sun.tools.attach.AttachPermission AttachPermission} 137 * <tt>("attachVirtualMachine")</tt>, or other permission 138 * required by the implementation. 139 * 140 * @throws AttachNotSupportedException 141 * If the identifier cannot be parsed, or it corresponds to 142 * to a Java virtual machine that does not exist, or it 143 * corresponds to a Java virtual machine which this 144 * provider cannot attach. 145 * 146 * @throws IOException 147 * If some other I/O error occurs 148 * 149 * @throws NullPointerException 150 * If <code>id</code> is <code>null</code> 151 */ 152 public abstract VirtualMachine attachVirtualMachine(String id) 153 throws AttachNotSupportedException, IOException; 154 155 /** 156 * Attaches to a Java virtual machine. 157 * 158 * <p> A Java virtual machine can be described using a {@link 159 * com.sun.tools.attach.VirtualMachineDescriptor VirtualMachineDescriptor}. 160 * This method invokes the descriptor's {@link 161 * com.sun.tools.attach.VirtualMachineDescriptor#provider() provider()} method 162 * to check that it is equal to this provider. It then attempts to attach to the 163 * Java virtual machine. 164 * 165 * @param vmd 166 * The virtual machine descriptor 167 * 168 * @return VirtualMachine representing the target virtual machine. 169 * 170 * @throws SecurityException 171 * If a security manager has been installed and it denies 172 * {@link com.sun.tools.attach.AttachPermission AttachPermission} 173 * <tt>("attachVirtualMachine")</tt>, or other permission 174 * required by the implementation. 175 * 176 * @throws AttachNotSupportedException 177 * If the descriptor's {@link 178 * com.sun.tools.attach.VirtualMachineDescriptor#provider() provider()} method 179 * returns a provider that is not this provider, or it does not correspond 180 * to a Java virtual machine to which this provider can attach. 181 * 182 * @throws IOException 183 * If some other I/O error occurs 184 * 185 * @throws NullPointerException 186 * If <code>vmd</code> is <code>null</code> 187 */ 188 public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd) 189 throws AttachNotSupportedException, IOException 190 { 191 if (vmd.provider() != this) { 192 throw new AttachNotSupportedException("provider mismatch"); 193 } 194 return attachVirtualMachine(vmd.id()); 195 } 196 197 /** 198 * Lists the Java virtual machines known to this provider. 199 * 200 * <p> This method returns a list of {@link 201 * com.sun.tools.attach.VirtualMachineDescriptor} elements. Each 202 * <code>VirtualMachineDescriptor</code> describes a Java virtual machine 203 * to which this provider can <i>potentially</i> attach. There isn't any 204 * guarantee that invoking {@link #attachVirtualMachine(VirtualMachineDescriptor) 205 * attachVirtualMachine} on each descriptor in the list will succeed. 206 * 207 * @return The list of virtual machine descriptors which describe the 208 * Java virtual machines known to this provider (may be empty). 209 */ 210 public abstract List<VirtualMachineDescriptor> listVirtualMachines(); 211 212 213 /** 214 * Returns a list of the installed attach providers. 215 * 216 * <p> An AttachProvider is installed on the platform if: 217 * 218 * <ul> 219 * <li><p>It is installed in a JAR file that is visible to the defining 220 * class loader of the AttachProvider type (usually, but not required 221 * to be, the {@link java.lang.ClassLoader#getSystemClassLoader system 222 * class loader}).</p></li> 223 * 224 * <li><p>The JAR file contains a provider configuration named 225 * <tt>com.sun.tools.attach.spi.AttachProvider</tt> in the resource directory 226 * <tt>META-INF/services</tt>. </p></li> 227 * 228 * <li><p>The provider configuration file lists the full-qualified class 229 * name of the AttachProvider implementation. </p></li> 230 * </ul> 231 * 232 * <p> The format of the provider configuration file is one fully-qualified 233 * class name per line. Space and tab characters surrounding each class name, 234 * as well as blank lines are ignored. The comment character is 235 * <tt>'#'</tt> (<tt>0x23</tt>), and on each line all characters following 236 * the first comment character are ignored. The file must be encoded in 237 * UTF-8. </p> 238 * 239 * <p> AttachProvider implementations are loaded and instantiated 240 * (using the zero-arg constructor) at the first invocation of this method. 241 * The list returned by the first invocation of this method is the list 242 * of providers. Subsequent invocations of this method return a list of the same 243 * providers. The list is unmodifable.</p> 244 * 245 * @return A list of the installed attach providers. 246 */ 247 public static List<AttachProvider> providers() { 248 synchronized (lock) { 249 if (providers == null) { 250 providers = new ArrayList<AttachProvider>(); 251 252 ServiceLoader<AttachProvider> providerLoader = 253 ServiceLoader.load(AttachProvider.class, 254 AttachProvider.class.getClassLoader()); 255 256 Iterator<AttachProvider> i = providerLoader.iterator(); 257 258 while (i.hasNext()) { 259 try { 260 providers.add(i.next()); 261 } catch (Throwable t) { 262 if (t instanceof ThreadDeath) { 263 ThreadDeath td = (ThreadDeath)t; 264 throw td; 265 } 266 // Ignore errors and exceptions 267 System.err.println(t); 268 } 269 } 270 } 271 return Collections.unmodifiableList(providers); 272 } 273 } 274 }