Skip to content

How it Works

Dave Townsend edited this page Feb 11, 2015 · 10 revisions

The following sections describe the various abstractions that you will work with when using Nicobar.

Script Module Loader

At the core of Nicobar is the ScriptModuleLoader. The module loader holds the runtime graph of loaded modules, and their interdependencies expressed as edges between the nodes in the graph. It provides the central runtime API for compiling, loading and serving script modules. Compiling and loading a script module is performed through the insertion of a Script Archive that result in a new Script Module being added to the graph, or an existing one becoming replaced.

The module loader can be queried at any time for loaded modules via a ModuleId which represents a unique module in the system. ModuleIds are a simple abstraction over a module name and a unique version number.

Queried script modules provide access to the compiled classes within the module. These classes can be further introspected, and methods on them exercised.

Script Archives

The ScriptArchive is equivalent to the source for an executable script module. The script archive is an abstraction representing the script source and resource files, as well as optional metadata (aka the ScriptModuleSpec) that describes how to create a module out of the archive. Script archives can contain mixed-language sources – i.e. if the author chooses to, different classes could be authored in a different JVM language as long as the ScriptModuleSpec describes the language compiler plugins that must process the archive.

Script archives can also contain compiled .class files, which would be faithfully loaded into the runtime module’s class loader.

Nicobar comes out of the box with three kinds of script archives: A SingleFileScriptArchive which can be pointed to a single source file on the system, a PathScriptArchive which is a directory containing script resources, and a JarScriptArchive which is a jar file containing script resources, can be created from.

Script Compiler Plugins

Nicobar module graphs are created with special vertices, which contain the ScriptCompilerPlugin (the language compiler interface, and a set of resources that provide the language runtime). An edge is added from a script module to a language plugin node, so that the language runtime is available to the script module. Correspondingly, every script archive declares a list of script language compilers which must be used to process the archive. The script module loader will run the archive iteratively through the declared list, and each language plugin will transform source into .class files that are loaded into the module constructed for the archive by the script module loader.

Thus to extend Nicobar to support new languages, new ScriptCompilerPlugins must be implemented.

Script Module Spec

The ScriptModuleSpec represents the Module descriptor for a script archive. The following metadata is described by a module spec:

  • Module ID
  • Custom metadata (map of string to object)
  • Module dependencies – a list of module IDs that this module is dependent on
  • Compiler Plugin IDs – a list of compiler plugins that must process this archive
  • App Import Filter Paths – A list of java package paths that must be allowed into the module from the application classpath
  • Module Import Filter Paths – A list of java package paths that must be allowed into the module from the modules it depends on
  • Module Export Filter Paths – A list of java package paths that must be allowed out of this module to other dependent modules

ScriptModuleSpecs can be described in code, or via static files that are present within or outside of a ScriptArchive. The default serialized format for a module specification is JSON, though other formats can be supported in an extensible way.

Script Modules

A ScriptModule is the final realization of a script archive in the runtime. Each script module represents a node in the module graph, and has a unique ModuleId. Under the hood, a script module is backed by a JBoss Module and a JBoss ModuleSpec created out of a ScriptModuleSpec and other runtime parameters. JBoss modules are powerful extensions to basic Java classloaders, and JBossModuleClassloaders are special classloaders with multiple parents, and package filters applied to incoming and outgoing edges. See the Module Dependencies and Module Visibility sections for more information.

A ScriptModule provides an interface to retrieve the list of classes held inside the module. These classes can be instantiated, and methods executed on the instances, thereby executing the script module.