changeset 1:6f180b7c6236

Fix agent instrumenting already loaded classes
author Omair Majid <omajid@redhat.com>
date Mon, 25 Aug 2014 11:42:44 -0400
parents 75652a041afb
children b225c94e1fa0
files agent/ProfileUsingJavassist.java
diffstat 1 files changed, 35 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ProfileUsingJavassist.java	Fri Aug 22 18:35:41 2014 -0400
+++ b/agent/ProfileUsingJavassist.java	Mon Aug 25 11:42:44 2014 -0400
@@ -17,19 +17,42 @@
 
 public class ProfileUsingJavassist {
 
+    private static List<String> ignorePackageRegexps = new ArrayList<>();
+
+    static {
+        // jdk packages
+        ignorePackageRegexps.add("java\\..*");
+        ignorePackageRegexps.add("javax\\..*");
+        ignorePackageRegexps.add("com\\.sun\\..*");
+        ignorePackageRegexps.add("sun\\..*");
+        ignorePackageRegexps.add("jdk\\..*");
+
+        // our library
+        ignorePackageRegexps.add("javassist\\..*");
+    }
+
     public static void premain(String agentArgs, Instrumentation instrumentation) {
         System.out.println("premain() called");
-        ClassInstrumenter profiler = new ClassInstrumenter();
-        instrumentation.addTransformer(profiler);
+        installProfiler(instrumentation);
     }
 
     public static void agentmain(String agentArgs, Instrumentation instrumentation) {
         System.out.println("agentmain() called");
 
-        ClassInstrumenter profiler = new ClassInstrumenter();
-        instrumentation.addTransformer(profiler);
+        installProfiler(instrumentation);
 
         for (Class<?> klass : instrumentation.getAllLoadedClasses()) {
+
+            if (klass.getName().startsWith(ProfileUsingJavassist.class.getName())) {
+                continue;
+            }
+
+            for (String regex : ignorePackageRegexps) {
+                if (klass.getName().matches(regex)) {
+                    continue;
+                }
+            }
+
             if (!instrumentation.isModifiableClass(klass)) {
                 continue;
             }
@@ -38,27 +61,20 @@
             try {
                 instrumentation.retransformClasses(classes);
             } catch (UnmodifiableClassException e) {
-                // TODO Auto-generated catch block
                 e.printStackTrace();
             }
+
         }
+    }
 
+    private static void installProfiler(Instrumentation instrumentation) {
+        ClassInstrumenter profiler = new ClassInstrumenter();
+        instrumentation.addTransformer(profiler, true);
     }
 
     static class ClassInstrumenter implements ClassFileTransformer {
 
         private static final String PREFIX = "thermostatMonitoringAgentGeneratedSynthetic";
-
-        private static List<String> ignorePackageRegexps = new ArrayList<>();
-
-        static {
-            ignorePackageRegexps.add("java\\..*");
-            ignorePackageRegexps.add("javax\\..*");
-            ignorePackageRegexps.add("com\\.sun\\..*");
-            ignorePackageRegexps.add("sun\\..*");
-            ignorePackageRegexps.add("jdk\\..*");
-        }
-
         @Override
         public byte[] transform(ClassLoader loader, String className,
                 Class<?> classBeingRedefined,
@@ -84,9 +100,9 @@
                     int modifiers = method.getModifiers();
                     if (!Modifier.isAbstract(modifiers) &&
                             !Modifier.isNative(modifiers)) {
-//                        method.addLocalVariable(PREFIX + "StartTime", CtClass.longType);
-//                        method.insertBefore(PREFIX + "StartTime = System.nanoTime();");
-//                        method.insertAfter("System.out.println(\"" + methodName + " took \" + (System.nanoTime() - " + PREFIX + "StartTime));");
+                        method.addLocalVariable(PREFIX + "StartTime", CtClass.longType);
+                        method.insertBefore(PREFIX + "StartTime = System.nanoTime();");
+                        method.insertAfter("System.out.println(\"" + methodName + " took \" + (System.nanoTime() - " + PREFIX + "StartTime));");
                     }
                 }
                 return klass.toBytecode();