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
}