package name.abishkar.javaagent;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClassFileTransformer implements ClassFileTransformer, Opcodes {
static final Logger logger = LoggerFactory.getLogger(MyClassFileTransformer.class);
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws IllegalClassFormatException {
logger.info("class file transformer invoked for className: {}", className);
if (className.equals("name/abishkar/user/MyUser")) {
ClassWriter cw = new ClassWriter(0);
MethodVisitor mv;
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "name/abishkar/user/MyUser", null,
"java/lang/Object", null);
cw.visitSource(null, null);
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(3, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "Lname/abishkar/user/MyUser;", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(6, l0);
mv.visitLdcInsn("bar");
mv.visitInsn(ARETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "Lname/abishkar/user/MyUser;", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
return classfileBuffer;
}
}
package name.abishkar.javaagent;
import java.lang.instrument.Instrumentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyJavaAgent {
static final Logger logger = LoggerFactory.getLogger(MyJavaAgent.class);
private static Instrumentation instrumentation;
/**
* JVM hook to statically load the javaagent at startup.
*
* After the Java Virtual Machine (JVM) has initialized, the premain method
* will be called. Then the real application main method will be called.
*
* @param args
* @param inst
* @throws Exception
*/
public static void premain(String args, Instrumentation inst) throws Exception {
logger.info("premain method invoked with args: {} and inst: {}", args, inst);
instrumentation = inst;
instrumentation.addTransformer(new MyClassFileTransformer());
}
/**
* JVM hook to dynamically load javaagent at runtime.
*
* The agent class may have an agentmain method for use when the agent is
* started after VM startup.
*
* @param args
* @param inst
* @throws Exception
*/
public static void agentmain(String args, Instrumentation inst) throws Exception {
logger.info("agentmain method invoked with args: {} and inst: {}", args, inst);
instrumentation = inst;
instrumentation.addTransformer(new MyClassFileTransformer());
}
/**
* Programmatic hook to dynamically load javaagent at runtime.
*/
public static void initialize() {
if (instrumentation == null) {
MyJavaAgentLoader.loadAgent();
}
}
}
package name.abishkar.javaagent;
import java.lang.management.ManagementFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.tools.attach.VirtualMachine;
public class MyJavaAgentLoader {
static final Logger logger = LoggerFactory.getLogger(MyJavaAgentLoader.class);
private static final String jarFilePath = "/home/abishkar/.m2/repository/"
+ "javaagent-examples/javaagent-examples/1.0/"
+ "javaagent-examples-1.0-jar-with-dependencies.jar";
public static void loadAgent() {
logger.info("dynamically loading javaagent");
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
int p = nameOfRunningVM.indexOf('@');
String pid = nameOfRunningVM.substring(0, p);
try {
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgent(jarFilePath, "");
vm.detach();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package name.abishkar.javaagent;
import java.util.Arrays;
import name.abishkar.user.MyUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyMainClass {
static final Logger logger = LoggerFactory.getLogger(MyMainClass.class);
static {
MyJavaAgent.initialize();
}
/**
* Main method.
*
* @param args
*/
public static void main(String[] args) {
logger.info("main method invoked with args: {}", Arrays.asList(args));
logger.info("userName: {}", new MyUser().getName());
}
}
No comments:
Post a Comment