Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluating javascript using a java code

This might not be practical, but I have it as a task. I have an opened ServerSocket in java. Now I want to read a file which contains html and javascript, and output the javascript result to the browser. So this way, I would be evaluating the javascript on the server side. So I want what is inside to be evaluated.

I tried this to test, it worked but it has some issues, for example it prints the message to System.out. And engine.eval("print('Welocme to java worldddd')"); does not return a String so that I can output it to the outputstream of the socket:

import javax.script.*;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
     // evaluate JavaScript code from String
     engine.eval("print('Welocme to java worldddd')");
     //engine.eval("a");
} catch (ScriptException ex) {
     Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
}
like image 588
Abdul Rahim Haddad Avatar asked Apr 03 '13 12:04

Abdul Rahim Haddad


2 Answers

You can get the output of the script (what is printed with print() in JavaScript) by setting the writer on the ScriptContext:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
ScriptContext context = engine.getContext();
StringWriter writer = new StringWriter();
context.setWriter(writer);

engine.eval("print('Welocme to java worldddd')");

String output = writer.toString();

System.out.println("Script output: " + output);
like image 90
Jesper Avatar answered Oct 07 '22 12:10

Jesper


I've solved this in the past by creating a javascript function inside eval() and invoking it to get a result:

import javax.script.*;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
     // evaluate JavaScript code from String
     engine.eval("function sum(a,b){ return a + b;}");
     System.out.println(((Invocable) engine).invokeFunction("sum", new Object[]{10,20}));
} catch (ScriptException ex) {
     Logger.getLogger(doComms.class.getName()).log(Level.SEVERE, null, ex);
}

Note that the function name in invokeFunction (first argument) should match the one declared previously.

Keep in mind that this might be dangerous. Do you have absolute control as to where the javascript code comes from? Otherwise a simple while(true){} could be pretty catastrophic for your server.

like image 23
Andre Avatar answered Oct 07 '22 14:10

Andre