private Object runScriptOrMainOrTestOrRunnable(Class scriptClass, String[] args) {
        // Always set the "args" property, regardless of what path we take in the code.
        // Bad enough to have side effects but worse if their behavior is wonky.
        context.setProperty("args", args);

        if (scriptClass == null) {
            return null;
        }

        //TODO: This logic mostly duplicates InvokerHelper.createScript.  They should probably be unified.

        if (Script.class.isAssignableFrom(scriptClass)) {
            // treat it just like a script if it is one
            try {
                Constructor constructor = scriptClass.getConstructor(Binding.class);
                Script script = (Script) constructor.newInstance(context);
                return script.run();
            } catch (InstantiationException e) {
                // ignore instantiation errors,, try to do main
            } catch (IllegalAccessException e) {
               // ignore instantiation errors, try to do main
            } catch (NoSuchMethodException e) {
                try {
                    // Fallback for non-standard "Scripts" that don't have contextual constructor.
                    Script script = (Script) scriptClass.newInstance();
                    script.setBinding(context);
                    return script.run();
                } catch (InstantiationException e1) {
                    // ignore instantiation errors, try to do main
                } catch (IllegalAccessException e1) {
                    // ignore instantiation errors, try to do main
                }
            } catch (InvocationTargetException e) {
                // ignore instantiation errors, try to do main
            }
        }
        try {
            // let's find a main method
            scriptClass.getMethod("main", new Class[]{String[].class});
            // if that main method exist, invoke it
            return InvokerHelper.invokeMethod(scriptClass, "main", new Object[]{args});
        } catch (NoSuchMethodException e) {
            // if it implements Runnable, try to instantiate it
            if (Runnable.class.isAssignableFrom(scriptClass)) {
                return runRunnable(scriptClass, args);
            }
            // if it's a JUnit 3.8.x test, run it with an appropriate runner
            if (isJUnit3Test(scriptClass)) {
                return runJUnit3Test(scriptClass);
            }
            // if it's a JUnit 3.8.x test suite, run it with an appropriate runner
            if (isJUnit3TestSuite(scriptClass)) {
                return runJUnit3TestSuite(scriptClass);
            }
            // if it's a JUnit 4.x test, run it with an appropriate runner
            if (isJUnit4Test(scriptClass)) {
                return runJUnit4Test(scriptClass);
            }
            for (Map.Entry<String, GroovyRunner> entry : GroovySystem.RUNNER_REGISTRY.entrySet()) {
                GroovyRunner runner = entry.getValue();
                if (runner != null && runner.canRun(scriptClass, this.loader)) {
                    return runner.run(scriptClass, this.loader);
                }
            }
            String message = "This script or class could not be run.\n" +
                    "It should either:\n" +
                    "- have a main method,\n" +
                    "- be a JUnit test or extend GroovyTestCase,\n" +
                    "- implement the Runnable interface,\n" +
                    "- or be compatible with a registered script runner. Known runners:\n";
            if (GroovySystem.RUNNER_REGISTRY.isEmpty()) {
                message += "  * <none>";
            }
            for (Map.Entry<String, GroovyRunner> entry : GroovySystem.RUNNER_REGISTRY.entrySet()) {
                message += "  * " + entry.getKey() + "\n";
            }
            throw new GroovyRuntimeException(message);
        }
    }
private Object runScriptOrMainOrTestOrRunnable ( Class scriptClass , String [ ] args ) { context . setProperty ( "args" , args ) ; if ( scriptClass == null ) { return null ; } if ( Script . class . isAssignableFrom ( scriptClass ) ) { try { Constructor constructor = scriptClass . getConstructor ( Binding . class ) ; Script script = ( Script ) constructor . newInstance ( context ) ; return script . run ( ) ; } catch ( InstantiationException e ) { } catch ( IllegalAccessException e ) { } catch ( NoSuchMethodException e ) { try { Script script = ( Script ) scriptClass . newInstance ( ) ; script . setBinding ( context ) ; return script . run ( ) ; } catch ( InstantiationException e1 ) { } catch ( IllegalAccessException e1 ) { } } catch ( InvocationTargetException e ) { } } try { scriptClass . getMethod ( "main" , new Class [ ] { String [ ] . class } ) ; return InvokerHelper . invokeMethod ( scriptClass , "main" , new Object [ ] { args } ) ; } catch ( NoSuchMethodException e ) { if ( Runnable . class . isAssignableFrom ( scriptClass ) ) { return runRunnable ( scriptClass , args ) ; } if ( isJUnit3Test ( scriptClass ) ) { return runJUnit3Test ( scriptClass ) ; } if ( isJUnit3TestSuite ( scriptClass ) ) { return runJUnit3TestSuite ( scriptClass ) ; } if ( isJUnit4Test ( scriptClass ) ) { return runJUnit4Test ( scriptClass ) ; } for ( Map . Entry < String , GroovyRunner > entry : GroovySystem . RUNNER_REGISTRY . entrySet ( ) ) { GroovyRunner runner = entry . getValue ( ) ; if ( runner != null && runner . canRun ( scriptClass , this . loader ) ) { return runner . run ( scriptClass , this . loader ) ; } } String message = "This script or class could not be run.\n" + "It should either:\n" + "- have a main method,\n" + "- be a JUnit test or extend GroovyTestCase,\n" + "- implement the Runnable interface,\n" + "- or be compatible with a registered script runner. Known runners:\n" ; if ( GroovySystem . RUNNER_REGISTRY . isEmpty ( ) ) { message += "  * <none>" ; } for ( Map . Entry < String , GroovyRunner > entry : GroovySystem . RUNNER_REGISTRY . entrySet ( ) ) { message += "  * " + entry . getKey ( ) + "\n" ; } throw new GroovyRuntimeException ( message ) ; } }
if (theClass is a Script) {
run it like a script
} else if (theClass has a main method) {
run the main method
} else if (theClass instanceof GroovyTestCase) {
use the test runner to run it
} else if (theClass implements Runnable) {
if (theClass has a constructor with String[] params)
instantiate theClass with this constructor and run
else if (theClass has a no-args constructor)
instantiate theClass with the no-args constructor and run
}