src/JavaRunner.java
public static void compile(String name, String code, int timeLimit){

        /*Creating dynamic java source code file object*/
        SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject (name, code) ;
        JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
        
        /*Instantiating the java compiler*/
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 
        /**
         * Retrieving the standard file manager from compiler object, which is used to provide
         * basic building block for customizing how a compiler reads and writes to files.
         *
         * The same file manager can be reopened for another compiler task.
         * Thus we reduce the overhead of scanning through file system and jar files each time
         */
        StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
        //uses custom file manager with defined class loader inorder to unload the compiled class when this is done
        ClassFileManager fileManager =  new ClassFileManager(stdFileManager);

        /* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
 
        /*Prepare any compilation options to be used during compilation*/
        //In this example, we are asking the compiler to place the output files under bin folder.
        List<String> compileOptions = new ArrayList<String>();
        compileOptions.addAll(Arrays.asList("-classpath", System.getProperty("java.class.path")));
        // Iterable<String> compilationOptionss = Arrays.asList(compileOptions);
 
        /*Create a diagnostic controller, which holds the compilation problems*/
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
 
        /*Create a compilation task from compiler by passing in the required input objects prepared above*/
        CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compileOptions, null, compilationUnits) ;
        
        //Perform the compilation by calling the call method on compilerTask object.
        boolean status = compilerTask.call();

        if (!status){//If compilation error occurs
            /*Iterate through each compilation problem and print it*/
            for (Diagnostic diagnostic : diagnostics.getDiagnostics()){
                System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
            }
        } else {
  
            try {
              fileManager.getClassLoader(null).loadClass(name).getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
            } catch (ClassNotFoundException e) {
              System.err.println("Class not found: " + e);
            } catch (NoSuchMethodException e) {
              System.err.println("No such method: " + e);
            } catch (IllegalAccessException e) {
              System.err.println("Illegal access: " + e);
            } catch (InvocationTargetException e) {
              // e.printStackTrace();
              // final StringWriter sw = new StringWriter();
              // final PrintWriter pw = new PrintWriter(sw, true);
              // e.getCause().printStackTrace(pw);
              // String trace = sw.getBuffer().toString();
              if (e.getCause() instanceof NoSuchElementException) { // becasue the exception occures in the Scanner we need to move up the stack trace
                // get the line where that triggered the scanner's read exception in the invoked program
                System.err.println("RuntimeError: java.util.NoSuchElementException: no more input\n\tat "+e.getCause().getStackTrace()[1].toString());
              } else {
                System.err.println("RuntimeError: "+e.getCause()+"\n\tat "+e.getCause().getStackTrace()[0].toString());
              }
            }

            try {
                fileObject.delete();
                fileManager.close();
                ResourceBundle.clearCache(ClassLoader.getSystemClassLoader()); // <--useless
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
/**
     * compiles and runs main method from code
     * @param name      Class Name
     * @param code      String to compile
     * @param timeLimit (otional) limit for code to run, default to 5 seconds
     */
compiles and runs main method from code
@param name      Class Name
@param code      String to compile
@param timeLimit (otional) limit for code to run, default to 5 seconds
compiles and runs main method from code @param name Class Name @param code String to compile @param timeLimit ( otional ) limit for code to run default to 5 seconds
public static void compile(String name, String code, int timeLimit){
        /*Creating dynamic java source code file object*/
        SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject (name, code) ;
        JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
        /*Instantiating the java compiler*/
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        /**
         * Retrieving the standard file manager from compiler object, which is used to provide
         * basic building block for customizing how a compiler reads and writes to files.
         *
         * The same file manager can be reopened for another compiler task.
         * Thus we reduce the overhead of scanning through file system and jar files each time
         */
        StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
        ClassFileManager fileManager =  new ClassFileManager(stdFileManager);
        /* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
        /*Prepare any compilation options to be used during compilation*/
        List<String> compileOptions = new ArrayList<String>();
        compileOptions.addAll(Arrays.asList("-classpath", System.getProperty("java.class.path")));
        /*Create a diagnostic controller, which holds the compilation problems*/
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
        /*Create a compilation task from compiler by passing in the required input objects prepared above*/
        CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compileOptions, null, compilationUnits) ;
        boolean status = compilerTask.call();
        if (!status){
            /*Iterate through each compilation problem and print it*/
            for (Diagnostic diagnostic : diagnostics.getDiagnostics()){
                System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
            }
        } else {
            try {
              fileManager.getClassLoader(null).loadClass(name).getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
            } catch (ClassNotFoundException e) {
              System.err.println("Class not found: " + e);
            } catch (NoSuchMethodException e) {
              System.err.println("No such method: " + e);
            } catch (IllegalAccessException e) {
              System.err.println("Illegal access: " + e);
            } catch (InvocationTargetException e) {
              if (e.getCause() instanceof NoSuchElementException) { 
                System.err.println("RuntimeError: java.util.NoSuchElementException: no more input\n\tat "+e.getCause().getStackTrace()[1].toString());
              } else {
                System.err.println("RuntimeError: "+e.getCause()+"\n\tat "+e.getCause().getStackTrace()[0].toString());
              }
            }
            try {
                fileObject.delete();
                fileManager.close();
                ResourceBundle.clearCache(ClassLoader.getSystemClassLoader()); 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
public static void compile ( String name , String code , int timeLimit ) { /*Creating dynamic java source code file object*/ SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject ( name , code ) ; JavaFileObject javaFileObjects [ ] = new JavaFileObject [ ] { fileObject } ; /*Instantiating the java compiler*/ JavaCompiler compiler = ToolProvider . getSystemJavaCompiler ( ) ; /**
         * Retrieving the standard file manager from compiler object, which is used to provide
         * basic building block for customizing how a compiler reads and writes to files.
         *
         * The same file manager can be reopened for another compiler task.
         * Thus we reduce the overhead of scanning through file system and jar files each time
         */ StandardJavaFileManager stdFileManager = compiler . getStandardFileManager ( null , null , null ) ; ClassFileManager fileManager = new ClassFileManager ( stdFileManager ) ; /* Prepare a list of compilation units (java source code file objects) to input to compilation task*/ Iterable < ? extends JavaFileObject > compilationUnits = Arrays . asList ( javaFileObjects ) ; /*Prepare any compilation options to be used during compilation*/ List < String > compileOptions = new ArrayList < String > ( ) ; compileOptions . addAll ( Arrays . asList ( "-classpath" , System . getProperty ( "java.class.path" ) ) ) ; /*Create a diagnostic controller, which holds the compilation problems*/ DiagnosticCollector < JavaFileObject > diagnostics = new DiagnosticCollector < JavaFileObject > ( ) ; /*Create a compilation task from compiler by passing in the required input objects prepared above*/ CompilationTask compilerTask = compiler . getTask ( null , fileManager , diagnostics , compileOptions , null , compilationUnits ) ; boolean status = compilerTask . call ( ) ; if ( ! status ) { /*Iterate through each compilation problem and print it*/ for ( Diagnostic diagnostic : diagnostics . getDiagnostics ( ) ) { System . err . format ( "Error on line %d in %s" , diagnostic . getLineNumber ( ) , diagnostic ) ; } } else { try { fileManager . getClassLoader ( null ) . loadClass ( name ) . getDeclaredMethod ( "main" , new Class [ ] { String [ ] . class } ) . invoke ( null , new Object [ ] { null } ) ; } catch ( ClassNotFoundException e ) { System . err . println ( "Class not found: " + e ) ; } catch ( NoSuchMethodException e ) { System . err . println ( "No such method: " + e ) ; } catch ( IllegalAccessException e ) { System . err . println ( "Illegal access: " + e ) ; } catch ( InvocationTargetException e ) { if ( e . getCause ( ) instanceof NoSuchElementException ) { System . err . println ( "RuntimeError: java.util.NoSuchElementException: no more input\n\tat " + e . getCause ( ) . getStackTrace ( ) [ 1 ] . toString ( ) ) ; } else { System . err . println ( "RuntimeError: " + e . getCause ( ) + "\n\tat " + e . getCause ( ) . getStackTrace ( ) [ 0 ] . toString ( ) ) ; } } try { fileObject . delete ( ) ; fileManager . close ( ) ; ResourceBundle . clearCache ( ClassLoader . getSystemClassLoader ( ) ) ; } catch ( IOException e ) { e . printStackTrace ( ) ; } } }
compiles and runs main method from code
 @param name      Class Name
 @param code      String to compile
 @param timeLimit (otional) limit for code to run, default to 5 seconds
compiles and runs main method from code @param name Class Name @param code String to compile @param timeLimit ( otional ) limit for code to run default to 5 seconds
//uses custom file manager with defined class loader inorder to unload the compiled class when this is done //In this example, we are asking the compiler to place the output files under bin folder. // Iterable<String> compilationOptionss = Arrays.asList(compileOptions); //Perform the compilation by calling the call method on compilerTask object. //If compilation error occurs // e.printStackTrace(); // final StringWriter sw = new StringWriter(); // final PrintWriter pw = new PrintWriter(sw, true); // e.getCause().printStackTrace(pw); // String trace = sw.getBuffer().toString(); // becasue the exception occures in the Scanner we need to move up the stack trace // get the line where that triggered the scanner's read exception in the invoked program // <--useless