svn commit: r889838 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/container/ start/src/org/ofbiz/base/start/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r889838 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/container/ start/src/org/ofbiz/base/start/

doogie-3
Author: doogie
Date: Fri Dec 11 22:26:24 2009
New Revision: 889838

URL: http://svn.apache.org/viewvc?rev=889838&view=rev
Log:
Generic instrumentation framework.  Nothing is configured to use it yet.

Added:
    ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Instrumenter.java
    ofbiz/trunk/framework/start/src/org/ofbiz/base/start/InstrumenterWorker.java
Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java
    ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Classpath.java
    ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java?rev=889838&r1=889837&r2=889838&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java Fri Dec 11 22:26:24 2009
@@ -49,6 +49,8 @@
     protected Classpath classPath = new Classpath(System.getProperty("java.class.path"));
     protected String configFileLocation = null;
     private boolean loaded = false;
+    private String instrumenterClassName;
+    private String instrumenterFile;
 
     /**
      * @see org.ofbiz.base.container.Container#init(java.lang.String[], java.lang.String)
@@ -70,10 +72,22 @@
         if (cc.getProperty("update-classpath") != null) {
             updateClassPath = "true".equalsIgnoreCase(cc.getProperty("update-classpath").value);
         }
+        String instrumenterClassName;
+        if (cc.getProperty("ofbiz.instrumenterClassName") != null) {
+            instrumenterClassName = cc.getProperty("ofbiz.instrumenterClassName").value;
+        } else {
+            instrumenterClassName = null;
+        }
+        String instrumenterFile;
+        if (cc.getProperty("ofbiz.instrumenterFile") != null) {
+            instrumenterFile = cc.getProperty("ofbiz.instrumenterFile").value;
+        } else {
+            instrumenterFile = null;
+        }
 
         // load the components
         try {
-            loadComponents(loaderConfig, updateClassPath);
+            loadComponents(loaderConfig, updateClassPath, instrumenterClassName, instrumenterFile);
         } catch (AlreadyLoadedException e) {
             throw new ContainerException(e);
         } catch (ComponentException e) {
@@ -89,6 +103,10 @@
     }
 
     public synchronized void loadComponents(String loaderConfig, boolean updateClasspath) throws AlreadyLoadedException, ComponentException {
+        loadComponents(loaderConfig, updateClasspath, null, null);
+    }
+
+    public synchronized void loadComponents(String loaderConfig, boolean updateClasspath, String instrumenterClassName, String instrumenterFile) throws AlreadyLoadedException, ComponentException {
         // set the loaded list; and fail if already loaded
         //if (loadedComponents == null) {
         //    loadedComponents = new LinkedList();
@@ -118,6 +136,7 @@
 
         // set the new classloader/classpath on the current thread
         if (updateClasspath) {
+            classPath.instrument(instrumenterFile, instrumenterClassName);
             System.setProperty("java.class.path", classPath.toString());
             ClassLoader cl = classPath.getClassLoader();
             Thread.currentThread().setContextClassLoader(cl);

Modified: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Classpath.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Classpath.java?rev=889838&r1=889837&r2=889838&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Classpath.java (original)
+++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Classpath.java Fri Dec 11 22:26:24 2009
@@ -88,6 +88,9 @@
         }
      }
 
+    public void instrument(String instrumenterFile, String instrumenterClassName) {
+        _elements = InstrumenterWorker.instrument(_elements, instrumenterFile, instrumenterClassName);
+    }
 
     @Override
     public String toString() {
@@ -128,6 +131,12 @@
         if (parent == null) {
             parent = ClassLoader.getSystemClassLoader();
         }
+        return getClassLoader(parent);
+    }
+
+    public ClassLoader getClassLoader(ClassLoader parent) {
+        URL[] urls = getUrls();
+
         return new URLClassLoader(urls, parent);
     }
 

Added: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Instrumenter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Instrumenter.java?rev=889838&view=auto
==============================================================================
--- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Instrumenter.java (added)
+++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Instrumenter.java Fri Dec 11 22:26:24 2009
@@ -0,0 +1,11 @@
+package org.ofbiz.base.start;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface Instrumenter {
+    File getDefaultFile() throws IOException;
+    void open(File dataFile, boolean forInstrumenting) throws IOException;
+    byte[] instrumentClass(byte[] bytes) throws IOException;
+    void close() throws IOException;
+}

Added: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/InstrumenterWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/InstrumenterWorker.java?rev=889838&view=auto
==============================================================================
--- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/InstrumenterWorker.java (added)
+++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/InstrumenterWorker.java Fri Dec 11 22:26:24 2009
@@ -0,0 +1,111 @@
+package org.ofbiz.base.start;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+public final class InstrumenterWorker {
+
+    public static final void copy(InputStream in, OutputStream out) throws IOException {
+        byte[] buf = new byte[4096];
+        int r;
+        while ((r = in.read(buf)) != -1) {
+            out.write(buf, 0, r);
+        }
+    }
+
+    public static List<File> instrument(List<File> srcPaths, String instrumenterFileName, String instrumenterClassName) {
+        if (instrumenterFileName == null) return srcPaths;
+        if (instrumenterClassName == null) return srcPaths;
+        Instrumenter instrumenter;
+        try {
+            List<URL> tmpUrls = new ArrayList<URL>();
+            for (File file: srcPaths) {
+                tmpUrls.add(file.toURI().toURL());
+            }
+            ClassLoader tmpLoader = new URLClassLoader(tmpUrls.toArray(new URL[tmpUrls.size()]), InstrumenterWorker.class.getClassLoader());
+            instrumenter = (Instrumenter) tmpLoader.loadClass(instrumenterClassName).newInstance();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+            return srcPaths;
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+            return srcPaths;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return srcPaths;
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            return srcPaths;
+        }
+        try {
+            File instrumenterFile = new File(instrumenterFileName);
+            instrumenterFile.delete();
+            instrumenter.open(instrumenterFile, true);
+            List<File> result = new ArrayList<File>();
+            for (File file: srcPaths) {
+                String path = file.getPath();
+                if (path.matches(".*/ofbiz[^/]*\\.(jar|zip)")) {
+                    System.err.println("instrumenting " + path);
+                    String prefix = path.substring(0, path.length() - 4);
+                    int slash = prefix.lastIndexOf("/");
+                    if (slash != -1) prefix = prefix.substring(slash + 1);
+                    prefix += "-";
+                    File zipTmp = File.createTempFile("instrumented-" + prefix, path.substring(path.length() - 4));
+                    try {
+                        zipTmp.deleteOnExit();
+                        ZipInputStream zin = new ZipInputStream(new FileInputStream(file));
+                        ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipTmp));
+                        ZipEntry entry;
+                        while ((entry = zin.getNextEntry()) != null) {
+                            InputStream in;
+                            long size;
+                            if (entry.getName().endsWith(".class")) {
+                                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                                copy(zin, baos);
+                                byte[] bytes = instrumenter.instrumentClass(baos.toByteArray());
+                                size = bytes.length;
+                                in = new ByteArrayInputStream(bytes);
+                            } else {
+                                in = zin;
+                                size = entry.getSize();
+                            }
+                            ZipEntry newEntry = new ZipEntry(entry);
+                            newEntry.setSize(size);
+                            newEntry.setCompressedSize(-1);
+                            zout.putNextEntry(newEntry);
+                            copy(in, zout);
+                            if (entry.getName().endsWith(".class")) {
+                                in.close();
+                            }
+                        }
+                        zout.close();
+                        file = zipTmp;
+                    } catch (IOException e) {
+                        zipTmp.delete();
+                        throw e;
+                    }
+                }
+                result.add(file);
+            }
+            instrumenter.close();
+            return result;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return srcPaths;
+        }
+    }
+}
+

Modified: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java?rev=889838&r1=889837&r2=889838&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java (original)
+++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java Fri Dec 11 22:26:24 2009
@@ -225,6 +225,7 @@
             classPath.addComponent(config.baseConfig);
         }
 
+        classPath.instrument(config.instrumenterFile, config.instrumenterClassName);
         // set the classpath/classloader
         System.setProperty("java.class.path", classPath.toString());
         this.classloader = classPath.getClassLoader();
@@ -447,6 +448,8 @@
         public String baseDtd;
         public String baseConfig;
         public String logDir;
+        public String instrumenterClassName;
+        public String instrumenterFile;
         public List<String> loaders;
         public String awtHeadless;
         public String splashLogo;
@@ -643,6 +646,9 @@
                 TimeZone.setDefault(TimeZone.getTimeZone(tzString));
             }
 
+            instrumenterClassName = getProp(props, "ofbiz.instrumenterClassName", null);
+            instrumenterFile = getProp(props, "ofbiz.instrumenterFile", null);
+
             // loader classes
             loaders = new ArrayList<String>();
             int currentPosition = 1;