-
Notifications
You must be signed in to change notification settings - Fork 298
NashornIntegration
The Nashorn module is used to run JavaScript on the server side by posting a script to an ResourceReference which is intended to execute it.
Before the script is actually executed it is translated into an AST (Abstract Syntax Tree) and abort statements are injected to prevent the script to run endless. If the script hits the maximum run duration the thread which executes it is going to be interrupted and all loops and function calls are going to be skipped.
Another feature is that you are able to monitor the actual allocated bytes of the thread which runs the script and abort the process if a given amount of memory is exceeded.
WebApplication:
public class NashornApplication extends WebApplication
{
private static NashornObject nashornObject = new NashornObject();
@Override
public Class<? extends Page> getHomePage()
{
return NashornPage.class;
}
@Override
protected void init()
{
// Initial thread pool of 10 concurrent scripts
// Maximum run duration 5 Seconds
// Memory check interval 10 seconds (optional)
// Allowed memory 31457280 => 30mb (optional, but requires check interval)
mountResource("/nashorn", new NashornResourceReference("nashorn", 10, 5, TimeUnit.SECONDS,
10, TimeUnit.MILLISECONDS, 31457280)
{
private static final long serialVersionUID = 1L;
@Override
protected void setup(Attributes attributes, Bindings bindings)
{
// which objects are going to be accessable
bindings.put("nashornObject", nashornObject);
}
@Override
protected Writer getWriter()
{
// Where to write output
return new BufferedWriter(new OutputStreamWriter(System.out));
}
@Override
protected Writer getErrorWriter()
{
// Where to write errors
return new BufferedWriter(new OutputStreamWriter(System.out));
}
@Override
protected boolean isDebug()
{
// Outputs AST information and other stuff while executing the actual script
return true;
}
@Override
protected ClassFilter getClassFilter()
{
// default is to allow nothing!
return new ClassFilter()
{
@Override
public boolean exposeToScripts(String name)
{
// which classes are allowed to be accessed (name is full qualified)
return false;
}
};
}
});
}
}
Simply post a JavaScript to http://<domain>:<port>/nashorn and access the nashornObject within that script. The last value / function call in that script is going to be returned as response. Example in which 3 is going to be returned to the client:
var x = 3;
x;
You are also able to add a security manager which is only activated within a thread running the scripts the implementation is NashornSecurityManager and used like this:
System.setProperty("java.security.policy",
MyClass.class.getResource("nashorn.policy").toString());
System.setSecurityManager(new NashornSecurityManager(false));
You have to grant access to every resource which is required within the script thread. An example can be found in the javadoc of the security manager itself. If you change the boolean to true the current thread is also checked by the manager.
- Nice tutorial for nashorn: http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/
- Oracle technology network article: http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html
- Oracle nashorn guids: https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
Beware that this integration try to make run scripts as safe as possible, but there are a lot of ways to may bypass this security attempts. So ensure not to make this interface public