[jboss-svn-commits] JBL Code SVN: r29679 - in labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent: submit and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Oct 20 06:01:19 EDT 2009


Author: adinn
Date: 2009-10-20 06:01:19 -0400 (Tue, 20 Oct 2009)
New Revision: 29679

Modified:
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Main.java
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Retransformer.java
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/TransformListener.java
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/submit/Submit.java
Log:
added ability to add jars to bootstrap classpath or system classpath either as -javaagent argument options or via the dynamic lsitener -- fixes for BYTEMAN-33

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Main.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Main.java	2009-10-20 09:41:23 UTC (rev 29678)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Main.java	2009-10-20 10:01:19 UTC (rev 29679)
@@ -47,10 +47,14 @@
         if (args != null) {
             // args are supplied eparated by ',' characters
             String[] argsArray = args.split(",");
-            // the only args we accept are extra jar files to be added to the boot path or scanned for rules
+            // we accept extra jar files to be added to the boot/sys classpaths
+            // script files to be scanned for rules
+            // listener flag which implies use of a retransformer
             for (String arg : argsArray) {
                 if (arg.startsWith(BOOT_PREFIX)) {
                     bootJarPaths.add(arg.substring(BOOT_PREFIX.length(), arg.length()));
+                } else if (arg.startsWith(SYS_PREFIX)) {
+                    sysJarPaths.add(arg.substring(SYS_PREFIX.length(), arg.length()));
                 } else if (arg.startsWith(SCRIPT_PREFIX)) {
                     scriptPaths.add(arg.substring(SCRIPT_PREFIX.length(), arg.length()));
                 } else if (arg.startsWith(LISTENER_PREFIX)) {
@@ -63,13 +67,12 @@
                 } else {
                     System.err.println("org.jboss.byteman.agent.Main:\n" +
                             "  illegal agent argument : " + arg + "\n" +
-                            "  valid arguments are boot:<path-to-jar>, script:<path-to-script> or listener:<true-or-false>");
+                            "  valid arguments are boot:<path-to-jar>, sys:<path-to-jar>, script:<path-to-script> or listener:<true-or-false>");
                 }
             }
         }
 
         // add any boot jars to the boot class path
-        // TODO can only do this when we get to 1.6
 
         for (String bootJarPath : bootJarPaths) {
             try {
@@ -81,6 +84,18 @@
             }
         }
 
+        // add any sys jars to the system class path
+
+        for (String sysJarPath : sysJarPaths) {
+            try {
+                JarFile jarfile = new JarFile(new File(sysJarPath));
+                inst.appendToSystemClassLoaderSearch(jarfile);
+            } catch (IOException ioe) {
+                System.err.println("org.jboss.byteman.agent.Main: unable to open system jar file : " + sysJarPath);
+                throw ioe;
+            }
+        }
+
         // look up rules in any script files
 
         for (String scriptPath : scriptPaths) {
@@ -154,6 +169,11 @@
     private static final String BOOT_PREFIX = "boot:";
 
     /**
+     * prefix used to specify system jar argument for agent
+     */
+    private static final String SYS_PREFIX = "sys:";
+
+    /**
      * prefix used to specify script argument for agent
      */
 
@@ -177,6 +197,11 @@
     private static List<String> bootJarPaths = new ArrayList<String>();
 
     /**
+     * list of paths to extra system jars supplied on command line
+     */
+    private static List<String> sysJarPaths = new ArrayList<String>();
+
+    /**
      * list of paths to script files supplied on command line
      */
     private static List<String> scriptPaths = new ArrayList<String>();

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Retransformer.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Retransformer.java	2009-10-20 09:41:23 UTC (rev 29678)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/Retransformer.java	2009-10-20 10:01:19 UTC (rev 29679)
@@ -25,6 +25,7 @@
 
 import java.lang.instrument.Instrumentation;
 import java.util.*;
+import java.util.jar.JarFile;
 import java.io.PrintWriter;
 
 /**
@@ -318,4 +319,15 @@
             out.println("uninstall RULE " + ruleScript.getName());
         }
     }
+
+    public void appendJarFile(PrintWriter out, JarFile jarfile, boolean isBoot) throws Exception
+    {
+        if (isBoot) {
+            inst.appendToBootstrapClassLoaderSearch(jarfile);
+            out.println("append boot jar " + jarfile.getName());
+        } else {
+            inst.appendToSystemClassLoaderSearch(jarfile);
+            out.println("append sys jar " + jarfile.getName());
+        }
+    }
 }

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/TransformListener.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/TransformListener.java	2009-10-20 09:41:23 UTC (rev 29678)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/TransformListener.java	2009-10-20 10:01:19 UTC (rev 29679)
@@ -9,6 +9,7 @@
 import java.io.*;
 import java.util.List;
 import java.util.LinkedList;
+import java.util.jar.JarFile;
 
 /**
  * a socket based listener class which reads scripts from stdin and installs them in the current runtime
@@ -144,7 +145,7 @@
             return;
         }
 
-p        BufferedReader in = new BufferedReader(new InputStreamReader(is));
+        BufferedReader in = new BufferedReader(new InputStreamReader(is));
         PrintWriter out = new PrintWriter(new OutputStreamWriter(os));
 
         String line = null;
@@ -160,6 +161,10 @@
                 out.println("ERROR");
                 out.println("Expecting input command");
                 out.println("OK");
+            } else if (line.equals("BOOT")) {
+                loadJars(in, out, true);
+            } else if (line.equals("SYS")) {
+                loadJars(in, out, false);
             } else if (line.equals("LOAD")) {
                 loadScripts(in, out);
             } else if (line.equals("DELETE")) {
@@ -191,6 +196,30 @@
         handleScripts(in, out, false);
     }
 
+    private void loadJars(BufferedReader in, PrintWriter out, boolean isBoot) throws IOException
+    {
+        String line = in.readLine().trim();
+        while (line != null && !line.equals("ENDBOOT")) {
+            try {
+                JarFile jarfile = new JarFile(new File(line));
+                retransformer.appendJarFile(out, jarfile, isBoot);
+            } catch (Exception e) {
+                out.append("EXCEPTION ");
+                out.append("Unable to add jar file " + line + "\n");
+                out.append(e.toString());
+                out.append("\n");
+                e.printStackTrace(out);
+            }
+            line = in.readLine().trim();
+        }
+        if (line == null || !line.equals("ENDBOOT")) {
+            out.append("ERROR\n");
+            out.append("Unexpected end of line reading boot jars\n");
+        }
+        out.println("OK");
+        out.flush();
+    }
+
     private void deleteScripts(BufferedReader in, PrintWriter out) throws IOException
     {
         handleScripts(in, out, true);
@@ -242,16 +271,14 @@
             } else {
                 retransformer.installScript(scripts, scriptNames, out);
             }
-            out.println("OK");
-            out.flush();
         } catch (Exception e) {
             out.append("EXCEPTION ");
             out.append(e.toString());
             out.append('\n');
             e.printStackTrace(out);
-            out.println("OK");
-            out.flush();
         }
+        out.println("OK");
+        out.flush();
     }
 
     private void purgeScripts(BufferedReader in, PrintWriter out) throws Exception

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/submit/Submit.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/submit/Submit.java	2009-10-20 09:41:23 UTC (rev 29678)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/agent/submit/Submit.java	2009-10-20 10:01:19 UTC (rev 29679)
@@ -4,6 +4,8 @@
 
 import java.io.*;
 import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Provide a main routine for an app which communicates with the byteman agent at runtime allowing loading,
@@ -16,19 +18,26 @@
      * main routine which submits a script to the byteman agent
      * @param args command line arguments specifying the script file(s) to be submitted and, optionally,
      * the byteman agent listener port to use.
-     * Submit [-p port] [-l|-d] [scriptfile . . .]
+     * Submit [-p port] [-l|-u] [scriptfile . . .]
+     * Submit [-p port] [-b|-s] jarfile . . .
      * -p port specifies theport to use
      * -l implies load/reload all rules found in supplied scripts
      *    or list all current rules if no scriptfile
      * -u implies unload all rules found in supplied scripts
      *    or unload all rules if no scriptfile
+     * -b jarfile implies install jar files into boot class path
+     * -s jarfile implies install jar files into system class path
      */
     public static void main(String[] args)
     {
         int port = TransformListener.DEFAULT_PORT;
         int startIdx = 0;
         int maxIdx = args.length;
+        boolean loadOrList = false;
         boolean deleteRules = false;
+        boolean addBoot = false;
+        boolean addSys = false;
+        int optionCount = 0;
 
         while (startIdx < maxIdx && args[startIdx].startsWith("-")) {
             if (maxIdx >= startIdx + 2 && args[startIdx].equals("-p")) {
@@ -46,18 +55,38 @@
             } else if (args[startIdx].equals("-u")) {
                 deleteRules = true;
                 startIdx++;
+                optionCount++;
             } else if (args[startIdx].equals("-l")) {
-                deleteRules = false;
+                loadOrList = true;
                 startIdx++;
+                optionCount++;
+            } else if (args[startIdx].equals("-b")) {
+                addBoot = true;
+                startIdx ++;
+                optionCount++;
+            } else if (args[startIdx].equals("-b")) {
+                addSys = true;
+                startIdx ++;
+                optionCount++;
             } else {
                 break;
             }
         }
 
-        if (startIdx < maxIdx && args[startIdx].startsWith("-")) {
+        if (startIdx < maxIdx && args[startIdx].startsWith("-") || optionCount > 1) {
             usage(1);
         }
 
+        if (optionCount == 0) {
+            loadOrList = true;
+        }
+
+        // must have some file args if adding to sys or boot classpath
+        
+        if (startIdx == maxIdx && (addBoot || addSys)) {
+            usage(1);
+        }
+        
         for (int i = startIdx; i < maxIdx; i++) {
             File file = new File(args[i]);
             if (!file.isFile() || !file.canRead()) {
@@ -117,7 +146,7 @@
         char[] readBuffer = new char[READ_BUFFER_LENGTH];
 
         if (startIdx == maxIdx) {
-            // no args means list or delete all current scripts;
+            // no args means list or delete all current scripts
             if (deleteRules) {
                 out.println("DELETEALL");
             } else {
@@ -125,7 +154,7 @@
             }
             out.flush();
             try {
-                String line = in.readLine();
+                String line = in.readLine().trim();
                 while (line != null && !line.equals("OK"))
                 {
                     System.out.println(line);
@@ -145,47 +174,66 @@
             }
         } else {
             StringBuffer stringBuffer = new StringBuffer();
-            if (deleteRules) {
-                stringBuffer.append("DELETE\n");
+            if (addBoot) {
+                stringBuffer.append("BOOT\n");
+                for (int i = startIdx; i < maxIdx; i++) {
+                    String name = args[i];
+                    stringBuffer.append(name);
+                    stringBuffer.append("\n");
+                }
+                stringBuffer.append("ENDBOOT\n");
+            } else if (addSys) {
+                stringBuffer.append("BOOT\n");
+                for (int i = startIdx; i < maxIdx; i++) {
+                    String name = args[i];
+                    stringBuffer.append(name);
+                    stringBuffer.append("\n");
+                }
+                stringBuffer.append("ENDBOOT\n");
             } else {
-                stringBuffer.append("LOAD\n");
-            }
-            for (int i = startIdx; i < maxIdx; i++) {
-                String name = args[i];
-                stringBuffer.append("SCRIPT " + name + "\n");
-                try {
-                    FileInputStream fis = new FileInputStream(args[i]);
-                    InputStreamReader reader = new InputStreamReader(fis);
-                    int read = reader.read(readBuffer);
-                    while (read > 0) {
-                        stringBuffer.append(readBuffer, 0, read);
-                        read = reader.read(readBuffer);
-                    }
-                    stringBuffer.append("ENDSCRIPT\n");
-                } catch (IOException e) {
-                    System.out.println("Submit : error reading from  file " + args[i] + " " + e);
-                    e.printStackTrace();
+                if (deleteRules) {
+                    stringBuffer.append("DELETE\n");
+                } else {
+                    stringBuffer.append("LOAD\n");
+                }
+                for (int i = startIdx; i < maxIdx; i++) {
+                    String name = args[i];
+                    stringBuffer.append("SCRIPT " + name + "\n");
                     try {
-                        socket.close();
-                    } catch (IOException e1) {
-                        System.out.println("Submit : exception closing socket after failed file read " + e1);
-                        e1.printStackTrace();
+                        FileInputStream fis = new FileInputStream(args[i]);
+                        InputStreamReader reader = new InputStreamReader(fis);
+                        int read = reader.read(readBuffer);
+                        while (read > 0) {
+                            stringBuffer.append(readBuffer, 0, read);
+                            read = reader.read(readBuffer);
+                        }
+                        reader.close();
+                        stringBuffer.append("ENDSCRIPT\n");
+                    } catch (IOException e) {
+                        System.out.println("Submit : error reading from  file " + args[i] + " " + e);
+                        e.printStackTrace();
+                        try {
+                            socket.close();
+                        } catch (IOException e1) {
+                            System.out.println("Submit : exception closing socket after failed file read " + e1);
+                            e1.printStackTrace();
+                        }
+
+                        System.exit(1);
                     }
-
-                    System.exit(1);
                 }
+                if (deleteRules) {
+                    stringBuffer.append("ENDDELETE\n");
+                } else {
+                    stringBuffer.append("ENDLOAD\n");
+                }
             }
-            if (deleteRules) {
-                stringBuffer.append("ENDDELETE\n");
-            } else {
-                stringBuffer.append("ENDLOAD\n");
-            }
             out.append(stringBuffer);
             out.flush();
 
             try {
-                String line = in.readLine();
-                while (line!= null & !line.equals("OK"))  {
+                String line = in.readLine().trim();
+                while (line != null & !line.equals("OK"))  {
                     System.out.println(line);
                     line = in.readLine();
                 }
@@ -207,11 +255,14 @@
     public static void usage(int exitCode)
     {
         System.out.println("usage : Submit [-p port] [-l|-u] [scriptfile . . .]");
+        System.out.println("        Submit [-p port] [-b|-s] jarfile . . .");
         System.out.println("        -p specifies listener port");
         System.out.println("        -l (default) with scriptfile(s) means load/reload all rules in scriptfile(s)");
         System.out.println("                     with no scriptfile means list all currently loaded rules");
         System.out.println("        -u with scriptfile(s) means unload all rules in scriptfile(s)");
         System.out.println("           with no scriptfile means unload all currently loaded rules");
+        System.out.println("        -b with jarfile(s) means add jars to bootstrap classpath");
+        System.out.println("        -s with jarfile(s) means add jars to system classpath");
         System.exit(exitCode);
     }
 }



More information about the jboss-svn-commits mailing list