Creating Javascript Function for Java Code

Description of the problem

A somewhat contrived example illustrating my question. Imagine that we have a library of javascript functions, which is already supported and updated daily by the army of frontend developers. To be specific, imagine that one of these functions looks like this:

function employeesForStore(store) { var dictionary = { "downtown": ["Joe", "Mary", "Steve"], "uptown": ["Jules", "Vincent", "Matt"], // and so on for hundreds of locations }; return dictionary[store]; } 

NOTE. Please ignore the implementation details of this function. The actual function can be much more complicated than a simple search in the JSON dictionary, and suppose we do not know any details about the implementation of the js function. We only know that it takes a String argument and returns an array of arrays.

Now we would like to use this feature in our Java code. That is, in our Java code, we would like to β€œload” this function, and then be able to call it several times, passing it String args and getting the results String[] or ArrayList<String> .

From searching SO and google so far, I understand that this will be related to using:

  • javax.script.ScriptEngineManager
  • javax.script.ScriptEngine
  • and possibly scriptEngine.getContext() to pass values ​​to a function and get the results.

I'm a little hazy about the details of the above, especially since most of the examples I found include running javascript code at a time, instead of using the javascript function for Java.

Sample code that I would like to see

  • Assuming the js function is in the file "my_functions.js", load this file in Java so that all its functions are available for use.
  • Call employeesForStore("downtown") and save its results in native java String[] or List<String> in a variable named downtownResults .
  • Same as 2, but call employeesForStore("uptown") and save uptownResults in the variable
+4
source share
2 answers

Create an interface to act like a facade in your JavaScript code.

Here is an example using the Rhino implementation implemented in the Oracle Java 1.7 implementation:

 package demo; import java.io.*; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import javax.script.*; public class StoreData { public static interface Stores { public String[] employees(String store); } public static Stores stores() throws IOException, ScriptException { ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine engine = sem.getEngineByName("JavaScript"); AtomicReference<Stores> ref = new AtomicReference<>(); engine.put("ref", ref); String adapt = "ref.set(" + "new Packages.demo.StoreData.Stores({employees:employeesForStore})" + ");"; try (Reader myFns = new FileReader("my_functions.js")) { // TODO encoding engine.eval(myFns); engine.eval(adapt); return ref.get(); } } public static void main(String[] args) throws IOException, ScriptException { List<String> employees = Arrays.asList(stores().employees("uptown")); System.out.println(employees); } } 

By specifying an interface, we let Rhino bind JavaScript types to Java types (String, String [], etc.)

The JRE specification does not provide any guarantees about which scripting mechanisms should be provided, so it may be wise to rely on an external engine. I don't know if that will change Nashorn .

+2
source

You can use Rhino API to run JS code in java

This tutorial covers the requested examples.

+2
source

All Articles