/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.vm.agent;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.lang.management.ManagementFactory;
import java.util.jar.JarFile;
import javax.management.MBeanServer;
import javax.management.NotificationBroadcasterSupport;
/**
* <p>Title: AgentInstrumentation</p>
* <p>Description: </p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.vm.agent.AgentInstrumentation</code></p>
*/
public class AgentInstrumentation extends NotificationBroadcasterSupport implements AgentInstrumentationMBean {
/** The instrumentation delegate */
protected final Instrumentation instrumentation;
/**
* The agent bootstrap entry point
* @param agentArgs The agent initialization arguments
* @param inst The instrumentation instance
*/
public static void agentmain(String agentArgs, Instrumentation inst) {
premain(agentArgs, inst);
}
/**
* The agent bootstrap entry point
* @param agentArgs The agent initialization arguments
* @param inst The instrumentation instance
*/
public static void premain(String agentArgs, Instrumentation inst) {
if(inst==null) {
System.err.println("Agent install failed. Instrumentation was null. Stack trace follows:");
new Throwable().fillInStackTrace().printStackTrace(System.err);
return;
}
System.out.println("Loading AgentInstrumentation MBean");
AgentInstrumentation ai = new AgentInstrumentation(inst);
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
if(server.isRegistered(AGENT_INSTR_ON)) {
server.unregisterMBean(AGENT_INSTR_ON);
}
server.registerMBean(ai, AGENT_INSTR_ON);
System.out.println("AgentInstrumentation MBean Loaded");
} catch (Exception e) {
System.err.println("Agent install failed. AgentInstrumentation MBean could not be registered. Stack trace follows:");
e.printStackTrace(System.err);
}
}
/**
* The agent bootstrap entry point which fails the install since there is no instrumentation
* @param agentArgs The agent initialization arguments
*/
public static void agentmain(String agentArgs) {
System.err.println("Agent install failed. Instrumentation was null. Stack trace follows:");
}
/**
* The agent bootstrap entry point which fails the install since there is no instrumentation
* @param agentArgs The agent initialization arguments
*/
public static void premain(String agentArgs) {
System.err.println("Agent install failed. Instrumentation was null. Stack trace follows:");
}
/**
* Creates a new AgentInstrumentation
* @param instrumentation The acquired instrumentation instance
*/
public AgentInstrumentation(Instrumentation instrumentation) {
super();
this.instrumentation = instrumentation;
}
// /**
// * Returns the byte code for the passed class
// * @param clazz The class to get the byte code for
// * @return the class bytecode or null if not found.
// */
// @Override
// public byte[] getByteCode(Class<?> clazz) {
// System.out.println("Retransformable [" + clazz.getName() + "]:" + this.isModifiableClass(clazz));
// byte[] bytecode = collector.getByteCode(clazz);
// if(bytecode==null) {
// try {
// this.retransformClasses(clazz);
// } catch (UnmodifiableClassException e) {
// e.printStackTrace();
// return null;
// }
// }
// bytecode = collector.getByteCode(clazz);
// if(bytecode==null) {
// System.out.println("Failed to Generate ByteCode for class [" + clazz.getName() + "]");
// } else {
// System.out.println("Generated ByteCode for class [" + clazz.getName() + "] --> [" + bytecode.length + "] Bytes.");
// }
//
// return bytecode;
// }
/**
* Returns the instrumentation agent
* @return the instrumentation agent
*/
@Override
public Instrumentation getInstrumentation() {
return instrumentation;
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
*/
@Override
public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
instrumentation.addTransformer(transformer, canRetransform);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#addTransformer(java.lang.instrument.ClassFileTransformer)
*/
@Override
public void addTransformer(ClassFileTransformer transformer) {
instrumentation.addTransformer(transformer);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#removeTransformer(java.lang.instrument.ClassFileTransformer)
*/
@Override
public boolean removeTransformer(ClassFileTransformer transformer) {
return instrumentation.removeTransformer(transformer);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#isRetransformClassesSupported()
*/
@Override
public boolean isRetransformClassesSupported() {
return instrumentation.isRetransformClassesSupported();
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#retransformClasses(java.lang.Class[])
*/
@Override
public void retransformClasses(Class<?>... classes) throws UnmodifiableClassException {
System.out.println("Retransforming [" + classes[0].getName() + "]");
instrumentation.retransformClasses(classes);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#isRedefineClassesSupported()
*/
@Override
public boolean isRedefineClassesSupported() {
return instrumentation.isRedefineClassesSupported();
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#redefineClasses(java.lang.instrument.ClassDefinition[])
*/
@Override
public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException {
instrumentation.redefineClasses(definitions);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#isModifiableClass(java.lang.Class)
*/
@Override
public boolean isModifiableClass(Class<?> theClass) {
return instrumentation.isModifiableClass(theClass);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#getAllLoadedClasses()
*/
@Override
public Class<?>[] getAllLoadedClasses() {
return instrumentation.getAllLoadedClasses();
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#getInitiatedClasses(java.lang.ClassLoader)
*/
@Override
public Class<?>[] getInitiatedClasses(ClassLoader loader) {
return instrumentation.getInitiatedClasses(loader);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#getObjectSize(java.lang.Object)
*/
@Override
public long getObjectSize(Object objectToSize) {
return instrumentation.getObjectSize(objectToSize);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch(java.util.jar.JarFile)
*/
@Override
public void appendToBootstrapClassLoaderSearch(JarFile jarfile) {
instrumentation.appendToBootstrapClassLoaderSearch(jarfile);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch(java.util.jar.JarFile)
*/
@Override
public void appendToSystemClassLoaderSearch(JarFile jarfile) {
instrumentation.appendToSystemClassLoaderSearch(jarfile);
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#isNativeMethodPrefixSupported()
*/
@Override
public boolean isNativeMethodPrefixSupported() {
return instrumentation.isNativeMethodPrefixSupported();
}
/**
* {@inheritDoc}
* @see java.lang.instrument.Instrumentation#setNativeMethodPrefix(java.lang.instrument.ClassFileTransformer, java.lang.String)
*/
@Override
public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
instrumentation.setNativeMethodPrefix(transformer, prefix);
}
}