`

CompilingClassLoader

    博客分类:
  • java
阅读更多
import java.io.*;   
  
/*  
 
A CompilingClassLoader compiles your Java source on-the-fly.  It checks  
for nonexistent .class files, or .class files that are older than their  
corresponding source code.  
 
*/  
  
public class CompilingClassLoader extends ClassLoader   
{   
  // Given a filename, read the entirety of that file from disk   
  // and return it as a byte array.   
  private byte[] getBytes( String filename ) throws IOException {   
    // Find out the length of the file   
    File file = new File( filename );   
    long len = file.length();   
  
    // Create an array that's just the right size for the file's   
    // contents   
    byte raw[] = new byte[(int)len];   
  
    // Open the file   
    FileInputStream fin = new FileInputStream( file );   
  
    // Read all of it into the array; if we don't get all,   
    // then it's an error.   
    int r = fin.read( raw );   
    if (r != len)   
      throw new IOException( "Can't read all, "+r+" != "+len );   
  
    // Don't forget to close the file!   
    fin.close();   
  
    // And finally return the file contents as an array   
    return raw;   
  }   
  
  // Spawn a process to compile the java source code file   
  // specified in the 'javaFile' parameter.  Return a true if   
  // the compilation worked, false otherwise.   
  private boolean compile( String javaFile ) throws IOException {   
    // Let the user know what's going on   
    System.out.println( "CCL: Compiling "+javaFile+"..." );   
  
    // Start up the compiler   
    Process p = Runtime.getRuntime().exec( "javac "+javaFile );   
  
    // Wait for it to finish running   
    try {   
      p.waitFor();   
    } catch( InterruptedException ie ) { System.out.println( ie ); }   
  
    // Check the return code, in case of a compilation error   
    int ret = p.exitValue();   
  
    // Tell whether the compilation worked   
    return ret==0;   
  }   
  
  // The heart of the ClassLoader -- automatically compile   
  // source as necessary when looking for class files   
  public Class loadClass( String name, boolean resolve )   
      throws ClassNotFoundException {   
  
    // Our goal is to get a Class object   
    Class clas = null;   
  
    // First, see if we've already dealt with this one   
    clas = findLoadedClass( name );   
  
    //System.out.println( "findLoadedClass: "+clas );   
  
    // Create a pathname from the class name   
    // E.g. java.lang.Object => java/lang/Object   
    String fileStub = name.replace( '.', '/' );   
  
    // Build objects pointing to the source code (.java) and object   
    // code (.class)   
    String javaFilename = fileStub+".java";   
    String classFilename = fileStub+".class";   
  
    File javaFile = new File( javaFilename );   
    File classFile = new File( classFilename );   
  
    //System.out.println( "j "+javaFile.lastModified()+" c "+   
    //  classFile.lastModified() );   
  
    // First, see if we want to try compiling.  We do if (a) there   
    // is source code, and either (b0) there is no object code,   
    // or (b1) there is object code, but it's older than the source   
    if (javaFile.exists() &&   
         (!classFile.exists() ||   
          javaFile.lastModified() > classFile.lastModified())) {   
  
      try {   
        // Try to compile it.  If this doesn't work, then   
        // we must declare failure.  (It's not good enough to use   
        // and already-existing, but out-of-date, classfile)   
        if (!compile( javaFilename ) || !classFile.exists()) {   
          throw new ClassNotFoundException( "Compile failed: "+javaFilename );   
        }   
      } catch( IOException ie ) {   
  
        // Another place where we might come to if we fail   
        // to compile   
        throw new ClassNotFoundException( ie.toString() );   
      }   
    }   
  
    // Let's try to load up the raw bytes, assuming they were   
    // properly compiled, or didn't need to be compiled   
    try {   
  
      // read the bytes   
      byte raw[] = getBytes( classFilename );   
  
      // try to turn them into a class   
      clas = defineClass( name, raw, 0, raw.length );   
    } catch( IOException ie ) {   
      // This is not a failure!  If we reach here, it might   
      // mean that we are dealing with a class in a library,   
      // such as java.lang.Object   
    }   
  
    //System.out.println( "defineClass: "+clas );   
  
    // Maybe the class is in a library -- try loading   
    // the normal way   
    if (clas==null) {   
      clas = findSystemClass( name );   
    }   
  
    //System.out.println( "findSystemClass: "+clas );   
  
    // Resolve the class, if any, but only if the "resolve"   
    // flag is set to true   
    if (resolve && clas != null)   
      resolveClass( clas );   
  
    // If we still don't have a class, it's an error   
    if (clas == null)   
      throw new ClassNotFoundException( name );   
  
    // Otherwise, return the class   
    return clas;   
  }   
}  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics