Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package edu.mit.simile.butterfly;
  
  import java.io.File;
  import java.net.URL;
  import java.util.HashMap;
  import java.util.Map;
 import java.util.Set;
 
This is Butterfly's own classloader that allows it to load classes and libraries from modules directly, instead of forcing them to be in the container's classpath or in the WEB-INF/(classes|lib) folders. This allows modules to be developed in isolation. Also, this classloader is capable of monitoring changes to the loaded classes (or to special files that we want watched for changes) and it's capable of executing a given Runnable action when such changes occur.
 
 public class ButterflyClassLoader extends URLClassLoader {
 
     private static final Logger _logger = LoggerFactory.getLogger("butterfly.classloader");
     
 
     public ButterflyClassLoader(ClassLoader parent) {
         super(new URL[0], parent);
     }
 
     public TimerTask getClassLoaderWatcher(Runnable trigger) {
         if ( == null) {
              = new ButterflyClassLoaderWatcher(trigger);
         }
         return ;
     }
     
     protected Class<?> loadClass(String nameboolean resolvethrows ClassNotFoundException {
 
         Class<?> clazz = findLoadedClass(name);
 
         if (clazz == null) {
             try {
                 .trace("Loading: {}"name);
                 clazz = findClass(name);
             } catch (ClassNotFoundException cnfe) {
             	try {
                     .trace("Parent loading: {}"name);
                     ClassLoader parent = getParent();
                     clazz = parent.loadClass(name);
             	} catch (ClassNotFoundException cnfe2) {
             		try {
 	                    .trace("Current loading: {}"name);
 	            		ClassLoader current = this.getClass().getClassLoader();
 	            		clazz = current.loadClass(name);
             		} catch (ClassNotFoundException cnfe3) {
 	                    .trace("System loading: {}"name);
 	            		ClassLoader system = ClassLoader.getSystemClassLoader();
 	            		clazz = system.loadClass(name);
             		}
             	}
             }
         }
 
         if (resolve) {
             resolveClass(clazz);
         }
 
         return clazz;
     }
 
     public void addRepository(File repository) {
     	.trace("> Processing class repository: {}"repository);
 
         if (repository.exists()) {
             if (repository.isDirectory()) {
                 File[] jars = repository.listFiles();
                 try  {
                 	.trace("Adding folder: {}"repository);
                     super.addURL(repository.toURI().toURL());
                     if (this. != null) {
                         this..addFile(repository);
                     }
                 } catch (MalformedURLException e) {
                     throw new IllegalArgumentException(e.toString());
                 }
 
                 for (int i = 0; i < jars.lengthi++) {
                     if (jars[i].getAbsolutePath().endsWith(".jar")) {
                         addJar(jars[i]);
                     }
                 }
             } else {
                addJar(repository);
            }
        } else {
            .info("Repository {} does not exist"repository);
        }
        .trace("< Processing class repository: {}"repository);
    }
    
    public void watch(File file) {
        if (this. != null) {
            this..watch(file);
        }
    }
    
    private void addJar(File file) {
        try  {
            URL url = file.toURI().toURL();
            .trace("Adding jar: {}"file);
            super.addURL(url);
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException(e.toString());
        }
    }
    final static private Logger _logger = LoggerFactory.getLogger("butterfly.classloader.watcher");
    
    private Set<Filefiles;
    private Map<File,LonglastModifieds;
    private Runnable trigger;
        this. = t;
        this. = new LinkedHashSet<File>();
        this. = new HashMap<File,Long>();
    }
        
    protected void addFile(File f) {
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (int i = 0; i < files.lengthi++) {
                addFile(files[i]);
            }
        } else {
            if (f.getName().endsWith(".jar") || f.getName().endsWith(".class")) {
                watch(f);
            } else {
                .debug("Not watching '{}' since it's not java bytecode."f);
            }
        }
    }
    
    protected void watch(File f) {
        .trace("Watching {}"f);
        synchronized(this) {
            this..add(f);
            this..put(f, Long.valueOf(f.lastModified()));
        }
    }
    
    public void run() {
        int counter = 0;
        
        synchronized(this) {
            for (File f : this.) {
                if (f.lastModified() > this..get(f).longValue()) {
                	.debug(f + " has changed");
                    this..put(f, Long.valueOf(f.lastModified()));
                    counter++;
                }
            }
        }
        
        if (counter > 0) {
            .debug("Classloading space has changed. Triggering the signal...");
            this..run();
            .debug("..done");
        }
    }
New to GrepCode? Check out our FAQ X