equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/NbInstrumentation.java
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
32 * If you wish your version of this file to be governed by only the CDDL
33 * or only the GPL Version 2, indicate your decision by adding
34 * "[Contributor] elects to include this software in this distribution
35 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36 * single choice of license, a recipient has the option to distribute
37 * your version of this file under either the CDDL, the GPL Version 2 or
38 * to extend the choice of license to its licensees as provided above.
39 * However, if you add GPL Version 2 code and therefore, elected the GPL
40 * Version 2 license, then the option applies only if the new code is
41 * made subject to such option by the copyright holder.
43 package org.netbeans.html.equinox.agentclass;
45 import java.lang.instrument.ClassDefinition;
46 import java.lang.instrument.ClassFileTransformer;
47 import java.lang.instrument.IllegalClassFormatException;
48 import java.lang.instrument.Instrumentation;
49 import java.lang.instrument.UnmodifiableClassException;
50 import java.lang.reflect.InvocationTargetException;
51 import java.lang.reflect.Method;
52 import java.security.ProtectionDomain;
53 import java.util.Collection;
54 import java.util.HashSet;
55 import java.util.List;
57 import java.util.concurrent.CopyOnWriteArrayList;
58 import java.util.jar.JarFile;
59 import java.util.logging.Level;
60 import java.util.logging.Logger;
64 * @author Jaroslav Tulach <jtulach@netbeans.org>
66 final class NbInstrumentation implements Instrumentation {
67 private static final Logger LOG = Logger.getLogger(NbInstrumentation.class.getName());
68 private static final Object LOCK = new Object();
69 private static volatile Collection<NbInstrumentation> ACTIVE;
71 private final List<ClassFileTransformer> transformers = new CopyOnWriteArrayList<ClassFileTransformer>();
72 private static final ThreadLocal<Boolean> IN = new ThreadLocal<Boolean>();
74 static NbInstrumentation registerAgent(ClassLoader l, String agentClassName) {
76 return registerImpl(agentClassName, l);
77 } catch (Throwable ex) {
78 LOG.log(Level.WARNING, "Cannot register " + agentClassName, ex);
82 static void unregisterAgent(NbInstrumentation instr) {
85 Collection<NbInstrumentation> clone = new HashSet<NbInstrumentation>();
92 private static NbInstrumentation registerImpl(String agentClassName, ClassLoader l) throws ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
93 final NbInstrumentation inst = new NbInstrumentation();
96 ACTIVE = new HashSet<NbInstrumentation>();
98 Set<NbInstrumentation> s = new HashSet<NbInstrumentation>();
104 Class<?> agentClass = Class.forName(agentClassName, true, l);
106 Method m = agentClass.getMethod("agentmain", String.class, Instrumentation.class); // NOI18N
107 m.invoke(null, "", inst);
108 } catch (NoSuchMethodException ex) {
109 Method m = agentClass.getMethod("agentmain", String.class); // NOI18N
115 public static byte[] patchByteCode(ClassLoader l, String className, ProtectionDomain pd, byte[] arr) throws IllegalClassFormatException {
116 if (ACTIVE == null) {
119 if (Boolean.TRUE.equals(IN.get())) {
123 IN.set(Boolean.TRUE);
124 for (NbInstrumentation inst : ACTIVE) {
125 for (ClassFileTransformer t : inst.transformers) {
126 arr = t.transform(l, className, null, pd, arr);
136 // Instrumentation methods
140 public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
141 transformers.add(transformer);
145 public void addTransformer(ClassFileTransformer transformer) {
146 transformers.add(transformer);
150 public boolean removeTransformer(ClassFileTransformer transformer) {
151 return transformers.remove(transformer);
155 public boolean isRetransformClassesSupported() {
160 public void retransformClasses(Class<?>... classes) throws UnmodifiableClassException {
161 throw new UnmodifiableClassException();
165 public boolean isRedefineClassesSupported() {
170 public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException {
171 throw new UnmodifiableClassException();
175 public boolean isModifiableClass(Class<?> theClass) {
180 public Class[] getAllLoadedClasses() {
185 public Class[] getInitiatedClasses(ClassLoader loader) {
190 public long getObjectSize(Object objectToSize) {
195 public void appendToBootstrapClassLoaderSearch(JarFile jarfile) {
199 public void appendToSystemClassLoaderSearch(JarFile jarfile) {
200 throw new UnsupportedOperationException();
204 public boolean isNativeMethodPrefixSupported() {
209 public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
210 throw new UnsupportedOperationException();