Exit Full View

Feather2 / documentation / RunningScripts.md

Running Scripts

So far, we have compiled some feather scripts, but haven't used/run them.

val result = compiler.compile( scripts )

result is of type CompilerResults. The most important thing it contains is the classLoader.

This ClassLoader can load the feather scripts that were just compiled, as well as deferring to its parent classloader to load other (non-feather) classes.

I'm now going to outline a few different scenarios. The example code is only an outline; you will almost certainly want to add additional error checking. These examples use Kotlin syntax; I hope Java coders can follow along too.

Running a function in the first class found

If you expect the compilation to create just one class, and you know the name of a function it should implement :

fun invokeGo(results: CompilationResults) {
    val className = results.allClassNames.first()
    val klass = results.classLoader.loadClass(className)
    // Look for a method called "go", which takes no arguments.
    val function = klass.getMethod("go")
    // We are assuming it is a `static method` (aka function), and therefore `obj` is `null`.
    function.invoke(null)
}

Run a named class implementing an interface

Let's suppose we know there should be a class called EntryPoint, which implements the interface Runnable :

val entryPointClass = result.classLoader.load( "EntryPoint" ) as Runnable
val runnable = entryPointClass.constructor().newInstance()
runnable.run()

Note. load takes a fully qualified class name (i.e. including the package name).

Note, that this example is not Feather-specific, we are only using Java's API.

Find all classes implementing an interface

We are going to use CompilerResults.allClassNames, then load each class in turn. Returning only those which are of type Runnable.

BTW, I'm only using Runnable as an example, replace it by the type you are interested in.

fun findRunnableClasses(results: CompilationResults): List<Class<*>> {
    val classes = mutableListOf<Class<*>>()
    for (className in results.allClassNames) {
        val klass = results.classLoader.loadClass(className)
        if (klass.isAssignableTo(Runnable::class.java)) {
            classes.add(klass)
        }
    }
    return classes
}

Back to Contents