Class CompilingClassLoader


  • @GwtIncompatible("java.lang.reflect.*")
    public class CompilingClassLoader
    extends java.lang.ClassLoader
    This is a Java ClassLoader that will attempt to load a class from a string of source code.

    Example

     String className = "com.foo.MyClass";
     String classSource =
       "package com.foo;\n" +
       "public class MyClass implements Runnable {\n" +
       "  @Override public void run() {\n" +
       "   log(\"Hello world\");\n" +
       "  }\n" +
       "}";
    
     // Load class from source.
     ClassLoader classLoader = new CompilingClassLoader(
         parentClassLoader, className, classSource);
     Class myClass = classLoader.loadClass(className);
    
     // Use it.
     Runnable instance = (Runnable)myClass.newInstance();
     instance.run();
     
    Only one chunk of source can be compiled per instance of CompilingClassLoader. If you need to compile more, create multiple CompilingClassLoader instances. Uses Java 1.6's in built compiler API. If the class cannot be compiled, loadClass() will throw a ClassNotFoundException and log the compile errors to System.err. If you don't want the messages logged, or want to explicitly handle the messages you can provide your own DiagnosticListener through {#setDiagnosticListener()}.
    See Also:
    ClassLoader, JavaCompiler
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.Map<java.lang.String,​java.io.ByteArrayOutputStream> byteCodeForClasses  
      private static java.net.URI EMPTY_URI  
    • Constructor Summary

      Constructors 
      Constructor Description
      CompilingClassLoader​(java.lang.ClassLoader parent, java.lang.String className, java.lang.String sourceCode, javax.tools.DiagnosticListener<javax.tools.JavaFileObject> diagnosticListener)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private boolean compileSourceCodeToByteCode​(java.lang.String className, java.lang.String sourceCode, javax.tools.DiagnosticListener<javax.tools.JavaFileObject> diagnosticListener)  
      java.lang.Class<?> findClass​(java.lang.String name)
      Override ClassLoader's class resolving method.
      • Methods inherited from class java.lang.ClassLoader

        clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findLibrary, findLoadedClass, findResource, findResources, findSystemClass, getClassLoadingLock, getPackage, getPackages, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, loadClass, registerAsParallelCapable, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • byteCodeForClasses

        private final java.util.Map<java.lang.String,​java.io.ByteArrayOutputStream> byteCodeForClasses
      • EMPTY_URI

        private static final java.net.URI EMPTY_URI
    • Constructor Detail

      • CompilingClassLoader

        public CompilingClassLoader​(java.lang.ClassLoader parent,
                                    java.lang.String className,
                                    java.lang.String sourceCode,
                                    javax.tools.DiagnosticListener<javax.tools.JavaFileObject> diagnosticListener)
                             throws CompilingClassLoader.CompilerException
        Parameters:
        parent - Parent classloader to resolve dependencies from.
        className - Name of class to compile. eg. "com.foo.MyClass".
        sourceCode - Java source for class. e.g. "package com.foo; class MyClass { ... }".
        diagnosticListener - Notified of compiler errors (may be null).
        Throws:
        CompilingClassLoader.CompilerException
    • Method Detail

      • findClass

        public java.lang.Class<?> findClass​(java.lang.String name)
                                     throws java.lang.ClassNotFoundException
        Override ClassLoader's class resolving method. Don't call this directly, instead use ClassLoader.loadClass(String).
        Overrides:
        findClass in class java.lang.ClassLoader
        Throws:
        java.lang.ClassNotFoundException
      • compileSourceCodeToByteCode

        private boolean compileSourceCodeToByteCode​(java.lang.String className,
                                                    java.lang.String sourceCode,
                                                    javax.tools.DiagnosticListener<javax.tools.JavaFileObject> diagnosticListener)
        Returns:
        Whether compilation was successful.