Package pkg = new Package();
pkg.set("someVariable".intern(), "any java object");
pkg.setConstant("someConstant".intern(), "any java object");
Context context = new Context(pkg);
Pnuts.load(scriptStreamUrlReaderOrString, context);
You can control whether scripts are interpreted, compiled, cached, etc with context.setImplementation:
http://pnuts.org/apidoc/pnuts/lang/PnutsImpl.html
Also, context.setVerbose is useful, and I like to call context.setWriter(new PrintWriter(System.out, true)); (the default PrintWriter doesn’t autoflush for whatever reason).
You can also pass in Pnuts functions in addition to objects:
pkg.setConstant("moo".intern(), new PnutsFunction () {
public boolean defined (int nargs) {
return nargs == 1;
}
protected Object exec (Object[] args, Context context) {
if (!defined(args.length)) undefined(args, context);
String someString = (String)args[0];
// Do stuff and return stuff.
return null;
}
public String toString () {
return "function moo(String)";
}
});
Another way to provide functionality to your scripts is the Pnuts module system. It is powerful and easy to use.
http://pnuts.org/1.2.1/snapshot/20070724/doc/lang.html#modules
Here is how you’d use a modified classloader with Pnuts, as kingaschi mentioned:
context.setClassLoader(new ClassLoader() {
protected synchronized Class<? > loadClass (String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("com.example.your.game.")) {
Class c = getParent().loadClass(name);
if (resolve) resolveClass(c);
return c;
}
throw new ClassNotFoundException("Unable to load class: " + name);
}
});
That seems a pretty secure way to prevent malicious classes from being loaded, but I would definitely hesitate to claim it is bulletproof without a lot more thought.