Skip to content

NashornIntegration

Andrea Del Bene edited this page Mar 6, 2016 · 12 revisions

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.

Setup

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; 
					}
				};
			}

		});
	}
}

Usage

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;

Security

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.

Links

Important!!!

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

Clone this wiki locally