JavaScript support in Schmant

Revision History
Revision 1.12010.02.16

Table of Contents

Running
Environment
Miscellaneous notes
JavaScript gotchas
Further reading
See also

JavaScript is supported through the Rhino script engine that is bundled with the Sun and IBM JDK:s or by a Rhino implementation downloaded from the Mozilla Rhino site. If both implementations are available, Schmant defaults to using the Rhino implementation that is not included in the JDK.

Before running a JavaScript build script, Schmant prepares the scripting environment by running the environment preparation script prepare.js. It enables the org.schmant.task.base task package, imports common Java, Schmant and EntityFS Java packages and defines the following functions:

debug(/* Object */ s)

Write a debug message to the current Report.

info(/* Object */ s)

Write an information message to the current Report.

warn(/* Object */ s)

Write a warning message to the current Report.

error(/* Object */ s)

Write an error message to the current Report.

fail(/* Object */ s)

Write an error message to the current Report and abort the build script execution.

enableTaskPackage(/* String */ name)

Enable the task package name.

include(/* Object */ f)

Execute the supplied script in the current script engine and return the result. The f argument is interpreted by InterpretAsReadableFileStrategy. JavaScript by itself lacks an import function.

Since include uses interpreted arguments, it can use files from a variety of locations. For large projects, for instance, it may be useful to distribute common utility functions in a Zip file.

Example 1. Including script files in a Zip archive

// Import the org.entityfs.zip Java package so that we don't have to qualify
// the ZipFileSystemBuilder class below.
importPackage(Packages.org.entityfs.zip);

// Get a Directory for the root directory of the Zip file
includeRoot = new ZipFileSystemBuilder().
  // Assuming that the script's working directory is an Eclipse workspace
  // directory, get the script archive from the Resources project
  setZipFile(new File("Resources/scripts/common-scripts.zip")).
  create().getRootDirectory();

// Include a couple of script files from the Zip file.
include(Directories.getFile(includeRoot, "common.js"));
include(Directories.getFile(includeRoot, "compile.js"));

The methods of SchmantUtil may be useful when creating paths relative to the currently executing script file.

reportError(/* Exception */ e)

Log error information from the exception to the error Report level. This can be useful for reporting errors directly in scripts since useful debugging information may otherwise get lost in the JavaScript script engine before it can be logged.


The following Java packages are imported by the environment preparation script:

Cannot call methods named "delete"

A JavaScript script cannot call methods named delete on objects. Probably because "delete" is a reserved word in JavaScript. This may also be a problem for other reserved words. See the Core JavaScript reference for a list of all reserved words in JavaScript.

Fully qualified class names may have to be prefixed with "Package."

You may run into errors like ReferenceError: "javax" is not defined, where javax may be org, com or any other name of a top level package. These errors occur because the JavaScript interpreter sometimes cannot resolve fully qualified classes, for some reason. A workaround is to prefix all package names with Packages. like this

importPackage(Packages.org.myproject.mypackage);

or

Packages.org.myproject.mypackage.MyClass.doIt(doItArgument);

JavaScript arrays do not work with overloaded methods in recent Rhino implementations.
Rhino bug #476041 causes JavaScript arrays to not work with overloaded methods. See for instance RecursiveActionTF, example four.

A good book for programmers that want to learn JavaScript is Douglas Crockford's JavaScript: The Good Parts. This Google TechTalk video gives a good idea of what to expect from the book.