commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Art Gramlich <...@gramlich-net.com>
Subject Re: [javaflow] Transforming classes that implement Continuable
Date Wed, 23 Feb 2005 23:12:55 GMT
On Wed, Feb 23, 2005 at 02:40:53PM -0700, Art Gramlich wrote:
> On Tue, Feb 22, 2005 at 08:08:01PM -0500, WHIRLYCOTT wrote:
> > Torsten Curdt wrote:
> > 
> > >While I did some work with ASM I found it
> > >very nice to work with ...and so I wanted
> > >get rid of a direct BCEL dependency. Which
> > 
> > Fyi, I'm working on porting the current BCEL ClassTransformer over to ASM.
> > 
> > >...but for now I think rewriting on the
> > >package name is quite a useable alternative
> > >that probably will fit the real world
> > >requirements.
> > 
> > You have mentioned this before, but I don't understand how you envision 
> > this working.  Does this mean that a class originally in package 
> > com.foo.abc would be rewritten to rewritten.package.name by the 
> > transformer?  I'm fairly sure that I am not interpreting your idea 
> > correctly because this will almost certainly cause problems for 
> > instances of that class if they need to access package protected methods 
> > and fields in other classes.  If you could go into a bit of detail on 
> > this, it would be super.
> 
> Sorry if I butt in.  What we were talking about is how to decide is a class
> should be transformed.  Right now, the ContinuationClassLoader is checking if
> the package name starts with "org.apache.commons.javaflow.testcode" and transforms
> it. Just for giggles, I just did a little patch to make that configurable (and a set).
> Any opinions?
> 
> Art Gramlich
> 
> 

Sorry, that last bit of code was wrong since it didn't check child packages...

It should be


Index: java/org/apache/commons/javaflow/ContinuationClassLoader.java
===================================================================
--- src/java/org/apache/commons/javaflow/ContinuationClassLoader.java	(revision 155031)
+++ src/java/org/apache/commons/javaflow/ContinuationClassLoader.java	(working copy)
@@ -17,6 +17,8 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.javaflow.bytecode.ClassTransformer;
@@ -33,66 +35,101 @@
     private final static Log log = LogFactory.getLog(ContinuationCompilingClassLoader.class);
     
     private ClassTransformer transformer = new BcelClassTransformer();
+    private Set packagesToTransform,packageRootsToTransform;
     
+    /*
     public ContinuationClassLoader(ClassLoader parent) {
+        this(parent, new HashSet());
+    }
+    */
+    
+    public ContinuationClassLoader(ClassLoader parent, Set packageRootsToTransform) {
         super(parent);
         //Repository.setRepository(new ClassLoaderRepository(parent));
+        this.packageRootsToTransform = packageRootsToTransform;
+        packagesToTransform = new TreeSet(packageRootsToTransform);
+    }
+    
+    protected boolean inPackageListOrSubPackage(String name) {
+	    int index = name.lastIndexOf('.');
+	    String packageName;
+	    if (index == -1) {
+	    		// If the class is in the default package, give the package name a single '.'
+	    		packageName = ".";
+	    } else {
+	    		packageName = name.substring(0,index);
+	    }
+	    boolean shouldTransform = packagesToTransform.contains(packageName);
+	    //log.debug("Checking if we should transform "+packageName+":"+shouldTransform);
+	    if (shouldTransform || packageName.equals(".")) {
+	    		return shouldTransform;
+	    } else {
+	    		return inPackageListOrSubPackage(packageName);
+	    }
+    }
+    
+    protected boolean shouldTransform(String name) {
+    	    boolean should = inPackageListOrSubPackage(name);
+    	    if (should || !packagesToTransform.contains(name)) {
+    	        packagesToTransform.add(name);	
+    	    }
+    	    return should;
     }
 
     protected synchronized Class loadClass(String name, boolean resolve)
-            throws ClassNotFoundException {
-        
-        Class c = findLoadedClass(name);
-
-        if (c == null) {
-            if (!name.startsWith("java.") &&
-                !name.startsWith("javax.") &&
-                !name.startsWith("sun.") &&
-                !name.startsWith("org.xml.") &&
-                !name.startsWith("org.w3c.") &&
-                !name.startsWith("org.apache.commons.logging.")
-                ) {
-
-                final InputStream is = super.getResourceAsStream(name.replace('.','/') +
".class");
-                
-                if (is != null) {
-                    
-                    if (name.startsWith("org.apache.commons.javaflow.testcode")) {
-                        //log.debug("transforming " + name);
-                        
-                        final byte data[] = transformer.transform(is);
-                        return defineClass(name, data, 0, data.length);
-                    }
-
-                    try {
-                        final byte data[] = IOUtils.toByteArray(is);
-                        
-                        //log.debug("loading "+ name);
-                        
-                        return defineClass(name, data, 0, data.length);            
-                    } catch (final IOException e) {
-                        throw new ClassNotFoundException("could not read class", e);
-                    }                    
-                } else {
-                    log.debug("could not find " + name);
-                }
-            }
-            
-            final ClassLoader parent = getParent();
-            if (parent != null) {
-                //log.debug("parent loading " + name);
-                c = parent.loadClass(name);
-            } else {
-                throw new ClassNotFoundException(name);
-            }
-
-        } else {
-            log.debug("already loaded " + name);
-        }
-        
-        if (resolve) {
-            resolveClass(c);
-        }
-        return c;
+	        throws ClassNotFoundException {
+	    
+	    Class c = findLoadedClass(name);
+	
+	    if (c == null) {
+	        if (!name.startsWith("java.") &&
+	            !name.startsWith("javax.") &&
+	            !name.startsWith("sun.") &&
+	            !name.startsWith("org.xml.") &&
+	            !name.startsWith("org.w3c.") &&
+	            !name.startsWith("org.apache.commons.logging.")
+	            ) {
+	
+	            final InputStream is = super.getResourceAsStream(name.replace('.','/') + ".class");
+	            
+	            if (is != null) {
+	                
+	                if (shouldTransform(name)) {
+	                    //log.debug("transforming " + name);
+	                    
+	                    final byte data[] = transformer.transform(is);
+	                    return defineClass(name, data, 0, data.length);
+	                }
+	
+	                try {
+	                    final byte data[] = IOUtils.toByteArray(is);
+	                    
+	                    //log.debug("loading "+ name);
+	                    
+	                    return defineClass(name, data, 0, data.length);            
+	                } catch (final IOException e) {
+	                    throw new ClassNotFoundException("could not read class", e);
+	                }                    
+	            } else {
+	                log.debug("could not find " + name);
+	            }
+	        }
+	        
+	        final ClassLoader parent = getParent();
+	        if (parent != null) {
+	            //log.debug("parent loading " + name);
+	            c = parent.loadClass(name);
+	        } else {
+	            throw new ClassNotFoundException(name);
+	        }
+	
+	    } else {
+	        log.debug("already loaded " + name);
+	    }
+	    
+	    if (resolve) {
+	        resolveClass(c);
+	    }
+	    return c;
+	}
     }
-}
Index: test/org/apache/commons/javaflow/AbstractClassLoaderTestCase.java
===================================================================
--- src/test/org/apache/commons/javaflow/AbstractClassLoaderTestCase.java	(revision 155031)
+++ src/test/org/apache/commons/javaflow/AbstractClassLoaderTestCase.java	(working copy)
@@ -16,7 +16,9 @@
 package org.apache.commons.javaflow;
 
 import java.lang.reflect.Method;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import junit.framework.TestCase;
 
@@ -35,7 +37,9 @@
     }
           
     protected void call(final String methodName) throws Exception {
-        final ClassLoader cl = new ContinuationClassLoader(getClass().getClassLoader());
+        Set packages = new HashSet();
+        packages.add("org.apache.commons.javaflow.testcode");
+    	    final ClassLoader cl = new ContinuationClassLoader(getClass().getClassLoader(),
packages);
         final Class clazz = cl.loadClass(clazzName);
         final Object instance = clazz.newInstance();
         assertNotNull(clazz);


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message