[jboss-cvs] JBoss Profiler SVN: r421 - in branches/JBossProfiler2: lib and 6 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Feb 14 11:26:43 EST 2008
Author: jesper.pedersen
Date: 2008-02-14 11:26:43 -0500 (Thu, 14 Feb 2008)
New Revision: 421
Added:
branches/JBossProfiler2/lib/javassist.jar
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledClass.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledMethod.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMTransformer.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/AbstractTransformer.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java
Removed:
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledClass.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledMethod.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Transformer.java
Modified:
branches/JBossProfiler2/doc/README.txt
branches/JBossProfiler2/src/etc/agent-manifest.mf
branches/JBossProfiler2/src/etc/jboss-profiler.properties
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Agent.java
branches/JBossProfiler2/src/main/org/jboss/profiler/client/Util.java
branches/JBossProfiler2/src/main/org/jboss/profiler/client/cmd/Client.java
branches/JBossProfiler2/src/main/org/jboss/profiler/shared/Visibility.java
branches/JBossProfiler2/src/test/org/jboss/profiler/test/Test.java
Log:
Javassist support and Visibility.PACKAGE
Modified: branches/JBossProfiler2/doc/README.txt
===================================================================
--- branches/JBossProfiler2/doc/README.txt 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/doc/README.txt 2008-02-14 16:26:43 UTC (rev 421)
@@ -67,7 +67,7 @@
load : Load a snapshot
save : Save a snapshot
diff : Compare snapshots
- add : Add classes (public|protected|private)
+ add : Add classes (public|package|protected|private)
remove : Remove classes
Host defaults to 'localhost'.
@@ -95,6 +95,9 @@
jboss-profiler.properties:
--------------------------
+core Specify the core framework to use
+ [javassist|asm] default: javassist
+
enable Enable / disable profiler
[yes|no] default: yes
@@ -113,7 +116,7 @@
f.ex: *
visibility The method visibility
- [public|protected|private] default: private
+ [public|package|protected|private] default: private
save Save snapshots on exit
[yes|no] default: yes
@@ -221,13 +224,13 @@
Deployment in JBoss Application Server:
---------------------------------------
+The steps below assumes that Javassist is used as the core library.
* Copy jboss-profiler.jar to jbossas/bin
* Copy jboss-profiler.properties to jbossas/bin
* Edit jboss-profiler.properties in jbossas/bin to include the classes to be profiled
* Copy jboss-profiler-plugins.jar to jbossas/bin
-* Copy asm.jar to jbossas/bin
-* Edit run.conf in jbossas/bin to include JBoss Profiler in JAVA_OPTS
+* Edit run.conf (Unix) or run.bat (Windows) in jbossas/bin to include JBoss Profiler in JAVA_OPTS
* Copy jboss-profiler.sar to jbossas/server/<conf>/deploy
* Boot application server
@@ -274,9 +277,10 @@
----------------------
The following libraries are needed
- x asm.jar (ASM 3.0)
+ x asm.jar (ASM 3.1)
x concurrent.jar (Oswego Concurrent)
x ejb3-persistence.jar (EJB3 Persistence API (test))
+ x javassist.jar (Javassist 3.7)
x jbossall-client.jar (JBoss client API (test))
x jboss-common.jar (JBoss Common)
x jboss-ejb3x.jar (EJB3 API (test))
Added: branches/JBossProfiler2/lib/javassist.jar
===================================================================
(Binary files differ)
Property changes on: branches/JBossProfiler2/lib/javassist.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: branches/JBossProfiler2/src/etc/agent-manifest.mf
===================================================================
--- branches/JBossProfiler2/src/etc/agent-manifest.mf 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/etc/agent-manifest.mf 2008-02-14 16:26:43 UTC (rev 421)
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Premain-Class: org.jboss.profiler.agent.Agent
Agent-Class: org.jboss.profiler.agent.Agent
-Boot-Class-Path: jboss-profiler.jar jboss-profiler-connectors.jar jboss-profiler-plugins.jar asm.jar jboss-remoting.jar jboss-common.jar concurrent.jar log4j.jar
+Boot-Class-Path: jboss-profiler.jar jboss-profiler-connectors.jar jboss-profiler-plugins.jar asm.jar javassist.jar ../lib/javassist.jar jboss-remoting.jar jboss-common.jar concurrent.jar log4j.jar
Can-Redefine-Classes: true
Can-Retransform-Classes: false
Can-Set-Native-Method-Prefix: false
Modified: branches/JBossProfiler2/src/etc/jboss-profiler.properties
===================================================================
--- branches/JBossProfiler2/src/etc/jboss-profiler.properties 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/etc/jboss-profiler.properties 2008-02-14 16:26:43 UTC (rev 421)
@@ -1,3 +1,4 @@
+core=javassist
enable=yes
cpu=yes
memory=yes
Copied: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledClass.java (from rev 420, branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledClass.java)
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledClass.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledClass.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
+
+import org.jboss.profiler.shared.Visibility;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Wraps a profiled class
+ * @author Jesper Pedersen <jep at worldleaguesports.com>
+ */
+public class ASMProfiledClass extends ClassAdapter {
+ /** The class name */
+ private String className;
+
+ /**
+ * Constructor
+ * @param visitor The class visitor
+ * @param className The class name
+ */
+ public ASMProfiledClass(ClassVisitor visitor, String className) {
+ super(visitor);
+ this.className = className;
+ }
+
+ /**
+ * Visit method
+ * @param access The access
+ * @param name The name
+ * @param descriptor The descriptor
+ * @param signature The signature
+ * @param exceptions The exceptions
+ * @return The method visitor
+ */
+ public MethodVisitor visitMethod(int access,
+ String name,
+ String descriptor,
+ String signature,
+ String[] exceptions) {
+
+ MethodVisitor mv = super.visitMethod(access,
+ name,
+ descriptor,
+ signature,
+ exceptions);
+
+ boolean include = true;
+
+ if ((access & Opcodes.ACC_PRIVATE) != 0) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PROTECTED ||
+ v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if ((access & Opcodes.ACC_PROTECTED) != 0) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if (access == 0) { // Package
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PUBLIC) {
+ include = false;
+ }
+ }
+ // Opcodes.ACC_PUBLIC -- no need to check for method visibility
+
+ if (include) {
+ if (descriptor != null) {
+ return new ASMProfiledMethod(mv, className, name + descriptor);
+ } else {
+ return new ASMProfiledMethod(mv, className, name);
+ }
+ }
+
+ return mv;
+ }
+}
Copied: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledMethod.java (from rev 420, branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledMethod.java)
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledMethod.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMProfiledMethod.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -0,0 +1,257 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Wraps a profiled method
+ * @author Jesper Pedersen <jep at worldleaguesports.com>
+ */
+public class ASMProfiledMethod extends MethodAdapter {
+
+ /** The class name */
+ private String className;
+
+ /** The method name */
+ private String methodName;
+
+ /** CINIT call */
+ private boolean clinit = false;
+
+ /** INIT call */
+ private boolean init = false;
+
+ /**
+ * Constructor
+ * @param visitor The visitor
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public ASMProfiledMethod(MethodVisitor visitor,
+ String className,
+ String methodName) {
+ super(visitor);
+ this.className = className;
+ this.methodName = methodName;
+
+ if ("<clinit>".equals(methodName)) {
+ this.clinit = true;
+ } else if (methodName.startsWith("<init>")) {
+ this.init = true;
+ }
+ }
+
+ /**
+ * Visit: Code
+ */
+ public void visitCode() {
+ if (clinit) {
+ super.visitCode();
+ return;
+ }
+
+ if (init) {
+ this.visitLdcInsn(className);
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "allocation",
+ "(Ljava/lang/String;)V");
+ }
+
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "start",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ super.visitCode();
+ }
+
+ /**
+ * Visit: Insn
+ * @param inst The instruction
+ */
+ public void visitInsn(int inst) {
+ if (clinit) {
+ super.visitInsn(inst);
+ return;
+ }
+
+ switch (inst) {
+ case Opcodes.ARETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.RETURN:
+ case Opcodes.ATHROW:
+
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "end",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ break;
+
+ default:
+ break;
+ }
+
+ if (Opcodes.MONITORENTER == inst) {
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "beginWait",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ super.visitInsn(inst);
+
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "endWait",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ } else {
+ super.visitInsn(inst);
+ }
+ }
+
+ /**
+ * Visit: Method inst
+ * @param opcode The opcode
+ * @param owner The owner
+ * @param name The name
+ * @param desc The description
+ */
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ if (isWaitInsn(opcode, owner, name, desc)) {
+
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "beginWait",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ super.visitMethodInsn(opcode, owner, name, desc);
+
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "endWait",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ } else {
+ super.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ /**
+ * Visit: Try / catch
+ * @param start The start label
+ * @param end The end label
+ * @param handler The handler label
+ * @param type The type
+ */
+ @Override
+ public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+ super.visitTryCatchBlock(start, end, handler, type);
+
+ if (type != null && !clinit) {
+ handler.info = new ExceptionInfo(type);
+ }
+ }
+
+ /**
+ * Visit: Label
+ * @param label The label
+ */
+ @Override
+ public void visitLabel(Label label) {
+ super.visitLabel(label);
+
+ if (label.info instanceof ExceptionInfo) {
+ this.visitLdcInsn(className);
+ this.visitLdcInsn(methodName);
+ this.visitLdcInsn(((ExceptionInfo)label.info).getType());
+
+ this.visitMethodInsn(Opcodes.INVOKESTATIC,
+ Profiler.CLASSNAME,
+ "unwind",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ }
+ }
+
+ /**
+ * Method: Waiting
+ * @param opcode The opcode
+ * @param owner The owner
+ * @param name The name
+ * @param desc The description
+ */
+ private static boolean isWaitInsn(int opcode, String owner, String name, String desc) {
+ boolean isWait = (opcode == Opcodes.INVOKEVIRTUAL
+ && "java/lang/Object".equals(owner)
+ && "wait".equals(name)
+ && ("()V".equals(desc) || "(J)V".equals(desc) || "(JI)V".equals(desc)));
+ if (isWait) {
+ return true;
+ }
+
+ isWait = (opcode == Opcodes.INVOKEVIRTUAL
+ && "java/lang/Thread".equals(owner)
+ && "join".equals(name)
+ && ("()V".equals(desc) || "(J)V".equals(desc) || "(JI)V".equals(desc)));
+ if (isWait) {
+ return true;
+ }
+
+ isWait = (opcode == Opcodes.INVOKESTATIC
+ && "java/lang/Thread".equals(owner)
+ && "sleep".equals(name)
+ && ("(J)V".equals(desc) || "(JI)V".equals(desc)));
+ if (isWait) {
+ return true;
+ }
+
+ isWait = (opcode == Opcodes.INVOKESTATIC
+ && "java/lang/Thread".equals(owner)
+ && "yield".equals(name)
+ && "()V".equals(desc));
+
+ return isWait;
+ }
+}
Copied: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMTransformer.java (from rev 420, branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Transformer.java)
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMTransformer.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ASMTransformer.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
+
+import java.io.IOException;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * Implements the ASM based transformer
+ * @author Jesper Pedersen <jep at worldleaguesports.com>
+ */
+public class ASMTransformer extends AbstractTransformer {
+
+ /**
+ * Constructor
+ */
+ public ASMTransformer() {
+ }
+
+ /**
+ * Generate instrumented class
+ * @param className The class name
+ * @param ob The original bytes
+ * @return The instrumented bytes
+ * @exception IOException If an error occurs
+ */
+ protected byte[] generateInstrumented(String className, byte[] ob) throws IOException {
+ ClassReader reader = new ClassReader(ob);
+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ ClassAdapter adapter = new ASMProfiledClass(writer, className);
+ reader.accept(adapter, ClassReader.SKIP_DEBUG);
+
+ return writer.toByteArray();
+ }
+}
Added: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/AbstractTransformer.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/AbstractTransformer.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/AbstractTransformer.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -0,0 +1,161 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.security.ProtectionDomain;
+
+/**
+ * An abstract transformer
+ * @author Jesper Pedersen <jep at worldleaguesports.com>
+ */
+public abstract class AbstractTransformer implements Transformer {
+
+ /**
+ * The transform method
+ * @param loader The class loader
+ * @param className The class name
+ * @param classBeingRedefined The class being redefined
+ * @param protectionDomain The protection domain
+ * @param classfileBuffer The class buffer
+ * @return The transformed class; null if no transformation have been done
+ * @exception IllegalClassFormatException If the class can't be transformed
+ */
+ public byte[] transform(ClassLoader loader,
+ String className,
+ Class<?> classBeingRedefined,
+ ProtectionDomain protectionDomain,
+ byte[] classfileBuffer) throws IllegalClassFormatException {
+
+ byte[] result = null;
+
+ if (Agent.isEnabled() && Agent.accept(className)) {
+ try {
+ if (Agent.isRepository() && !ClassRepository.exists(className, loader)) {
+ ClassRepository.save(className, loader, classfileBuffer);
+ }
+
+ byte[] buffer = null;
+ if (classBeingRedefined != null) {
+ buffer = loadNonInstrumented(className, loader);
+ }
+ if (buffer == null) {
+ buffer = classfileBuffer;
+ }
+
+ result = generateInstrumented(className, buffer);
+
+ } catch (Throwable t) {
+ IllegalClassFormatException ice = new IllegalClassFormatException(t.getMessage());
+ ice.initCause(t);
+ throw ice;
+ }
+ } else if (classBeingRedefined != null) {
+ try {
+ result = loadNonInstrumented(className, loader);
+ } catch (Throwable t) {
+ IllegalClassFormatException ice = new IllegalClassFormatException(t.getMessage());
+ ice.initCause(t);
+ throw ice;
+ }
+ }
+ if (Agent.isRepository() &&
+ className.indexOf("$Proxy") != -1 &&
+ !ClassRepository.exists(className, loader)) {
+ try {
+ // Create backup of all proxy classes regardless of policy
+ ClassRepository.save(className, loader, classfileBuffer);
+ } catch (Throwable t) {
+ //
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Load non instrumented class
+ * @param className The class name
+ * @param loader The class loader
+ * @return The bytes
+ * @exception IOException If an error occurs
+ */
+ public byte[] loadNonInstrumented(String className, ClassLoader loader) throws IOException {
+ byte[] clz = null;
+ className = className.replace(".", "/");
+
+ if (Agent.isRepository() && ClassRepository.exists(className, loader)) {
+ clz = ClassRepository.load(className, loader);
+ } else if (loader != null) {
+ InputStream is = null;
+ try {
+ is = loader.getResourceAsStream(className + ".class");
+
+ if (is != null) {
+ BufferedInputStream bis = new BufferedInputStream(is);
+ clz = new byte[bis.available()];
+ int n = bis.read(clz);
+ }
+
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ioe) {
+ //
+ }
+ }
+ }
+
+ if (Agent.isRepository() && !ClassRepository.exists(className, loader) && clz != null) {
+ ClassRepository.save(className, loader, clz);
+ }
+ }
+
+ return clz;
+ }
+
+ /**
+ * Load instrumented class
+ * @param className The class name
+ * @param loader The class loader
+ * @return The bytes
+ * @exception IOException If an error occurs
+ */
+ public byte[] loadInstrumented(String className, ClassLoader loader) throws IOException {
+ byte[] clz = loadNonInstrumented(className, loader);
+
+ return generateInstrumented(className, clz);
+ }
+
+ /**
+ * Generate instrumented class
+ * @param className The class name
+ * @param ob The original bytes
+ * @return The instrumented bytes
+ * @exception IOException If an error occurs
+ */
+ protected abstract byte[] generateInstrumented(String className, byte[] ob) throws IOException;
+}
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Agent.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Agent.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Agent.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -54,6 +54,9 @@
*/
public class Agent {
+ /** Use Javassist */
+ private static boolean useJavassist;
+
/** Transformer */
private static Transformer transformer;
@@ -188,6 +191,8 @@
visibility = parseVisibility(vs);
visibilityTree = new TreeMap(new SizeComparator());
+ useJavassist = parseCore(properties.getProperty("core"), true);
+
ejb = parseBoolean(properties.getProperty("ejb"), true);
servlet = parseBoolean(properties.getProperty("servlet"), true);
jsf = parseBoolean(properties.getProperty("jsf"), true);
@@ -249,6 +254,8 @@
if (vs != null) {
if ("public".equalsIgnoreCase(vs)) {
return Visibility.PUBLIC;
+ } else if ("package".equalsIgnoreCase(vs)) {
+ return Visibility.PACKAGE;
} else if ("protected".equalsIgnoreCase(vs)) {
return Visibility.PROTECTED;
}
@@ -257,6 +264,25 @@
}
/**
+ * Parse core property (Javassist or ASM library)
+ * @param p The property value
+ * @param def The default value
+ * @return True or false
+ */
+ private static boolean parseCore(String p, boolean def) {
+ if (p != null) {
+ p = p.trim();
+ if ("ASM".equalsIgnoreCase(p)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ return def;
+ }
+
+ /**
* Parse include / exclude lists
* @param include The include input
* @param exclude The exclude input
@@ -513,18 +539,20 @@
* @return True if the class is approved; otherwise false
*/
private static boolean approve(String className) {
- // We can't profile the profiler, Java / Sun classes nor ASM
- if (className.startsWith("org/jboss/profiler/agent") ||
- className.startsWith("org/jboss/profiler/as") ||
- className.startsWith("org/jboss/profiler/shared") ||
- className.startsWith("org/jboss/profiler/client") ||
- className.startsWith("org/jboss/profiler/connectors") ||
- className.startsWith("org/jboss/profiler/plugins") ||
+ // We can't profile the profiler, Java / Sun classes
+ // nor ASM and Javassist whichever is used
+ if (className.startsWith("org/jboss/profiler/agent/") ||
+ className.startsWith("org/jboss/profiler/as/") ||
+ className.startsWith("org/jboss/profiler/client/") ||
+ className.startsWith("org/jboss/profiler/connectors/") ||
+ className.startsWith("org/jboss/profiler/plugins/") ||
+ className.startsWith("org/jboss/profiler/shared/") ||
className.startsWith("java/") ||
className.startsWith("javax/") ||
className.startsWith("sun/") ||
className.startsWith("com/sun/") ||
- className.startsWith("org/objectweb/asm/")) {
+ (!useJavassist && className.startsWith("org/objectweb/asm/")) ||
+ (useJavassist && className.startsWith("javassist/"))) {
return false;
}
@@ -823,15 +851,18 @@
String key = s.substring(0, s.indexOf("="));
String value = s.substring(s.indexOf("=") + 1);
- if ("enable".equals(key)) {
+ if ("enable".equalsIgnoreCase(key)) {
enabled = parseBoolean(value, enabled);
}
- if ("remote".equals(key)) {
+ if ("remote".equalsIgnoreCase(key)) {
remote = parseBoolean(value, remote);
}
- if ("quite".equals(key)) {
+ if ("quite".equalsIgnoreCase(key)) {
quite = parseBoolean(value, quite);
}
+ if ("core".equalsIgnoreCase(key)) {
+ useJavassist = parseCore(value, useJavassist);
+ }
}
}
@@ -844,7 +875,11 @@
System.out.println("JBoss Profiler not enabled");
}
- transformer = new Transformer();
+ if (useJavassist) {
+ transformer = new JavassistTransformer();
+ } else {
+ transformer = new ASMTransformer();
+ }
instrumentation = inst;
instrumentation.addTransformer(transformer);
Added: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
+
+import org.jboss.profiler.shared.Visibility;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import javassist.Modifier;
+
+/**
+ * Implements the Javssist based transformer
+ * @author Jesper Pedersen <jep at worldleaguesports.com>
+ */
+public class JavassistTransformer extends AbstractTransformer {
+
+ /**
+ * Constructor
+ */
+ public JavassistTransformer() {
+ }
+
+ /**
+ * Generate instrumented class
+ * @param className The class name
+ * @param ob The original bytes
+ * @return The instrumented bytes
+ * @exception IOException If an error occurs
+ */
+ protected byte[] generateInstrumented(String className, byte[] ob) throws IOException {
+ try {
+ ClassPool pool = ClassPool.getDefault();
+ ByteArrayInputStream bis = new ByteArrayInputStream(ob);
+
+ CtClass cc = pool.makeClass(bis);
+ CtConstructor[] constructors = cc.getDeclaredConstructors();
+ for (int i = 0; i < constructors.length; i++) {
+ CtConstructor constructor = constructors[i];
+ instrumentConstructor(constructor, className);
+ }
+
+ CtMethod[] methods = cc.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ CtMethod method = methods[i];
+ instrumentMethod(method, className);
+ }
+
+ return cc.toBytecode();
+
+ } catch (Exception e) {
+ IOException ioe = new IOException(e.getMessage());
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+
+ /**
+ * Instrument constructor
+ * @param constructor The constructor
+ * @param className The class name
+ * @exception CannotCompileException If the constructor cant be modified
+ */
+ private void instrumentConstructor(CtConstructor constructor, String className) throws CannotCompileException {
+ if (!constructor.isClassInitializer()) {
+ boolean include = true;
+
+ if (Modifier.isPrivate(constructor.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PROTECTED ||
+ v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if (Modifier.isProtected(constructor.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if (Modifier.isPackage(constructor.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PUBLIC) {
+ include = false;
+ }
+ }
+ // Modifier.PUBLIC -- no need to check for method visibility
+
+ if (include) {
+ constructor.insertBeforeBody("{ " +
+ "org.jboss.profiler.agent.Profiler.allocation(\"" + className +"\");" +
+ "org.jboss.profiler.agent.Profiler.start(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
+ " }");
+
+ constructor.insertAfter("{ " +
+ "org.jboss.profiler.agent.Profiler.end(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
+ " }", true);
+ }
+ }
+ }
+
+ /**
+ * Instrument method
+ * @param method The method
+ * @param className The class name
+ * @exception CannotCompileException If the constructor cant be modified
+ */
+ private void instrumentMethod(CtMethod method, String className) throws CannotCompileException {
+ boolean include = true;
+
+ if (Modifier.isPrivate(method.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PROTECTED ||
+ v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if (Modifier.isProtected(method.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PACKAGE ||
+ v == Visibility.PUBLIC) {
+ include = false;
+ }
+ } else if (Modifier.isPackage(method.getModifiers())) {
+ Visibility v = Agent.getVisibility(className);
+ if (v == Visibility.PUBLIC) {
+ include = false;
+ }
+ }
+ // Modifier.PUBLIC -- no need to check for method visibility
+
+ if (include) {
+ method.insertBefore("{ " +
+ "org.jboss.profiler.agent.Profiler.start(\"" + className + "\", \"" + method.getLongName() + "\");" +
+ " }");
+
+ method.insertAfter("{ " +
+ "org.jboss.profiler.agent.Profiler.end(\"" + className + "\", \"" + method.getLongName() + "\");" +
+ " }", true);
+ }
+ }
+}
Deleted: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledClass.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledClass.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledClass.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -1,96 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
-
-import org.jboss.profiler.shared.Visibility;
-
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Wraps a profiled class
- * @author Jesper Pedersen <jep at worldleaguesports.com>
- */
-public class ProfiledClass extends ClassAdapter {
- /** The class name */
- private String className;
-
- /**
- * Constructor
- * @param visitor The class visitor
- * @param className The class name
- */
- public ProfiledClass(ClassVisitor visitor, String className) {
- super(visitor);
- this.className = className;
- }
-
- /**
- * Visit method
- * @param access The access
- * @param name The name
- * @param descriptor The descriptor
- * @param signature The signature
- * @param exceptions The exceptions
- * @return The method visitor
- */
- public MethodVisitor visitMethod(int access,
- String name,
- String descriptor,
- String signature,
- String[] exceptions) {
-
- MethodVisitor mv = super.visitMethod(access,
- name,
- descriptor,
- signature,
- exceptions);
-
- boolean include = true;
-
- if ((access & Opcodes.ACC_PRIVATE) != 0) {
- Visibility v = Agent.getVisibility(className);
- if (v == Visibility.PROTECTED ||
- v == Visibility.PUBLIC) {
- include = false;
- }
- } else if ((access & Opcodes.ACC_PROTECTED) != 0) {
- Visibility v = Agent.getVisibility(className);
- if (v == Visibility.PUBLIC) {
- include = false;
- }
- }
- // Opcodes.ACC_PUBLIC -- no need to check for method visibility
-
- if (include) {
- if (descriptor != null) {
- return new ProfiledMethod(mv, className, name + descriptor);
- } else {
- return new ProfiledMethod(mv, className, name);
- }
- }
-
- return mv;
- }
-}
Deleted: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledMethod.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledMethod.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfiledMethod.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -1,257 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
-
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Wraps a profiled method
- * @author Jesper Pedersen <jep at worldleaguesports.com>
- */
-public class ProfiledMethod extends MethodAdapter {
-
- /** The class name */
- private String className;
-
- /** The method name */
- private String methodName;
-
- /** CINIT call */
- private boolean clinit = false;
-
- /** INIT call */
- private boolean init = false;
-
- /**
- * Constructor
- * @param visitor The visitor
- * @param className The class name
- * @param methodName The method name
- */
- public ProfiledMethod(MethodVisitor visitor,
- String className,
- String methodName) {
- super(visitor);
- this.className = className;
- this.methodName = methodName;
-
- if ("<clinit>".equals(methodName)) {
- this.clinit = true;
- } else if (methodName.startsWith("<init>")) {
- this.init = true;
- }
- }
-
- /**
- * Visit: Code
- */
- public void visitCode() {
- if (clinit) {
- super.visitCode();
- return;
- }
-
- if (init) {
- this.visitLdcInsn(className);
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "allocation",
- "(Ljava/lang/String;)V");
- }
-
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "start",
- "(Ljava/lang/String;Ljava/lang/String;)V");
-
- super.visitCode();
- }
-
- /**
- * Visit: Insn
- * @param inst The instruction
- */
- public void visitInsn(int inst) {
- if (clinit) {
- super.visitInsn(inst);
- return;
- }
-
- switch (inst) {
- case Opcodes.ARETURN:
- case Opcodes.DRETURN:
- case Opcodes.FRETURN:
- case Opcodes.IRETURN:
- case Opcodes.LRETURN:
- case Opcodes.RETURN:
- case Opcodes.ATHROW:
-
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "end",
- "(Ljava/lang/String;Ljava/lang/String;)V");
- break;
-
- default:
- break;
- }
-
- if (Opcodes.MONITORENTER == inst) {
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "beginWait",
- "(Ljava/lang/String;Ljava/lang/String;)V");
-
- super.visitInsn(inst);
-
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "endWait",
- "(Ljava/lang/String;Ljava/lang/String;)V");
- } else {
- super.visitInsn(inst);
- }
- }
-
- /**
- * Visit: Method inst
- * @param opcode The opcode
- * @param owner The owner
- * @param name The name
- * @param desc The description
- */
- @Override
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
- if (isWaitInsn(opcode, owner, name, desc)) {
-
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "beginWait",
- "(Ljava/lang/String;Ljava/lang/String;)V");
-
- super.visitMethodInsn(opcode, owner, name, desc);
-
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "endWait",
- "(Ljava/lang/String;Ljava/lang/String;)V");
- } else {
- super.visitMethodInsn(opcode, owner, name, desc);
- }
- }
-
- /**
- * Visit: Try / catch
- * @param start The start label
- * @param end The end label
- * @param handler The handler label
- * @param type The type
- */
- @Override
- public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
- super.visitTryCatchBlock(start, end, handler, type);
-
- if (type != null && !clinit) {
- handler.info = new ExceptionInfo(type);
- }
- }
-
- /**
- * Visit: Label
- * @param label The label
- */
- @Override
- public void visitLabel(Label label) {
- super.visitLabel(label);
-
- if (label.info instanceof ExceptionInfo) {
- this.visitLdcInsn(className);
- this.visitLdcInsn(methodName);
- this.visitLdcInsn(((ExceptionInfo)label.info).getType());
-
- this.visitMethodInsn(Opcodes.INVOKESTATIC,
- Profiler.CLASSNAME,
- "unwind",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- }
- }
-
- /**
- * Method: Waiting
- * @param opcode The opcode
- * @param owner The owner
- * @param name The name
- * @param desc The description
- */
- private static boolean isWaitInsn(int opcode, String owner, String name, String desc) {
- boolean isWait = (opcode == Opcodes.INVOKEVIRTUAL
- && "java/lang/Object".equals(owner)
- && "wait".equals(name)
- && ("()V".equals(desc) || "(J)V".equals(desc) || "(JI)V".equals(desc)));
- if (isWait) {
- return true;
- }
-
- isWait = (opcode == Opcodes.INVOKEVIRTUAL
- && "java/lang/Thread".equals(owner)
- && "join".equals(name)
- && ("()V".equals(desc) || "(J)V".equals(desc) || "(JI)V".equals(desc)));
- if (isWait) {
- return true;
- }
-
- isWait = (opcode == Opcodes.INVOKESTATIC
- && "java/lang/Thread".equals(owner)
- && "sleep".equals(name)
- && ("(J)V".equals(desc) || "(JI)V".equals(desc)));
- if (isWait) {
- return true;
- }
-
- isWait = (opcode == Opcodes.INVOKESTATIC
- && "java/lang/Thread".equals(owner)
- && "yield".equals(name)
- && "()V".equals(desc));
-
- return isWait;
- }
-}
Deleted: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Transformer.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Transformer.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Transformer.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -1,165 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2007, Red Hat Middleware LLC, 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.jboss.profiler.agent;
-
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.security.ProtectionDomain;
-
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-
-/**
- * Implements the transformer
- * @author Jesper Pedersen <jep at worldleaguesports.com>
- */
-public class Transformer implements ClassFileTransformer {
-
- /**
- * The transform method
- * @param loader The class loader
- * @param className The class name
- * @param classBeingRedefined The class being redefined
- * @param protectionDomain The protection domain
- * @param classfileBuffer The class buffer
- * @return The transformed class; null if no transformation have been done
- * @exception IllegalClassFormatException If the class can't be transformed
- */
- public byte[] transform(ClassLoader loader,
- String className,
- Class<?> classBeingRedefined,
- ProtectionDomain protectionDomain,
- byte[] classfileBuffer) throws IllegalClassFormatException {
-
- byte[] result = null;
-
- if (Agent.isEnabled() && Agent.accept(className)) {
- try {
- if (Agent.isRepository() && !ClassRepository.exists(className, loader)) {
- ClassRepository.save(className, loader, classfileBuffer);
- }
-
- byte[] buffer = null;
- if (classBeingRedefined != null) {
- buffer = loadNonInstrumented(className, loader);
- }
- if (buffer == null) {
- buffer = classfileBuffer;
- }
-
- ClassReader reader = new ClassReader(buffer);
- ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- ClassAdapter adapter = new ProfiledClass(writer, className);
- reader.accept(adapter, ClassReader.SKIP_DEBUG);
- result = writer.toByteArray();
- } catch (Throwable t) {
- IllegalClassFormatException ice = new IllegalClassFormatException(t.getMessage());
- ice.initCause(t);
- throw ice;
- }
- } else if (classBeingRedefined != null) {
- try {
- result = loadNonInstrumented(className, loader);
- } catch (Throwable t) {
- IllegalClassFormatException ice = new IllegalClassFormatException(t.getMessage());
- ice.initCause(t);
- throw ice;
- }
- }
- if (Agent.isRepository() &&
- className.indexOf("$Proxy") != -1 &&
- !ClassRepository.exists(className, loader)) {
- try {
- // Create backup of all proxy classes regardless of policy
- ClassRepository.save(className, loader, classfileBuffer);
- } catch (Throwable t) {
- //
- }
- }
-
- return result;
- }
-
- /**
- * Load instrumented class
- * @param className The class name
- * @param loader The class loader
- * @return The bytes
- * @exception IOException If an error occurs
- */
- public byte[] loadInstrumented(String className, ClassLoader loader) throws IOException {
- byte[] clz = loadNonInstrumented(className, loader);
-
- ClassReader reader = new ClassReader(clz);
- ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- ClassAdapter adapter = new ProfiledClass(writer, className);
- reader.accept(adapter, ClassReader.SKIP_DEBUG);
-
- return writer.toByteArray();
- }
-
- /**
- * Load non instrumented class
- * @param className The class name
- * @param loader The class loader
- * @return The bytes
- * @exception IOException If an error occurs
- */
- public byte[] loadNonInstrumented(String className, ClassLoader loader) throws IOException {
- byte[] clz = null;
- className = className.replace(".", "/");
-
- if (Agent.isRepository() && ClassRepository.exists(className, loader)) {
- clz = ClassRepository.load(className, loader);
- } else if (loader != null) {
- InputStream is = null;
- try {
- is = loader.getResourceAsStream(className + ".class");
-
- if (is != null) {
- BufferedInputStream bis = new BufferedInputStream(is);
- clz = new byte[bis.available()];
- int n = bis.read(clz);
- }
-
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException ioe) {
- //
- }
- }
- }
-
- if (Agent.isRepository() && !ClassRepository.exists(className, loader) && clz != null) {
- ClassRepository.save(className, loader, clz);
- }
- }
-
- return clz;
- }
-}
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/client/Util.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/client/Util.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/client/Util.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -114,6 +114,43 @@
* @return The pretty name
*/
public static String getPrettyName(MethodInfo mi) {
+ // Javassist
+ if (mi.getMethodName().endsWith(")")) {
+ int start = mi.getMethodName().indexOf("(");
+ int dot = mi.getMethodName().indexOf(".");
+
+ StringBuffer sb = new StringBuffer(mi.getMethodName().substring(0, start + 1));
+
+ if (dot != -1 && dot < start) {
+ sb.setCharAt(sb.lastIndexOf("."), '#');
+ }
+
+ if (start + 1 < mi.getMethodName().indexOf(")")) {
+ String[] params = mi.getMethodName().substring(start + 1, mi.getMethodName().indexOf(")")).split(",");
+ for (int i = 0; i < params.length; i++) {
+ String clz = params[i];
+
+ int jl = clz.indexOf("java.lang");
+ if (jl != -1) {
+ if (clz.indexOf(".", jl + 10) == -1) {
+ clz = clz.replace("java.lang.", "");
+ }
+ }
+
+ sb = sb.append(clz);
+
+ if (i < params.length - 1) {
+ sb = sb.append(", ");
+ }
+ }
+ }
+
+ sb = sb.append(")");
+
+ return sb.toString();
+ }
+
+ // ASM
StringBuffer sb = new StringBuffer(mi.getClassName().replace('/', '.'));
sb = sb.append('#');
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/client/cmd/Client.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/client/cmd/Client.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/client/cmd/Client.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -219,6 +219,8 @@
v = Visibility.PRIVATE;
} else if (args[i + 1].equalsIgnoreCase("protected")) {
v = Visibility.PROTECTED;
+ } else if (args[i + 1].equalsIgnoreCase("package")) {
+ v = Visibility.PACKAGE;
}
cmd = new Command(CommandType.ADD_CLASSES, new Object[] { clz, v } );
i++;
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/shared/Visibility.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/shared/Visibility.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/shared/Visibility.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -38,6 +38,11 @@
PROTECTED,
/**
+ * Package
+ */
+ PACKAGE,
+
+ /**
* Public
*/
PUBLIC
Modified: branches/JBossProfiler2/src/test/org/jboss/profiler/test/Test.java
===================================================================
--- branches/JBossProfiler2/src/test/org/jboss/profiler/test/Test.java 2008-02-10 10:59:33 UTC (rev 420)
+++ branches/JBossProfiler2/src/test/org/jboss/profiler/test/Test.java 2008-02-14 16:26:43 UTC (rev 421)
@@ -101,6 +101,12 @@
}
/**
+ * Method: F
+ */
+ void f() {
+ }
+
+ /**
* The main method
* @param args The arguments
*/
@@ -117,6 +123,7 @@
t.b();
t.c();
t.e();
+ t.f();
System.out.println("Done.");
}
}
More information about the jboss-cvs-commits
mailing list