1

I want to get a javascript object from a javascript file, that only constists of this one big object. For example:

var cars = {
   mercedes: {
      colour: 'silver',
      drivemode: 'alldrive' 
   },

   audi: {
      size: '4x2x1,5m'
      speed: '220 kmph'
   }
};

For the javapart I am using rhino to get that object. For now I have coded:

Context context = context.enter();
context.setOptimizationLevel(9);
context.setLangaugeVersion(170);
context.getWrapFactory().setJavaPrimitiveWrap(false);

Scriptable defaultScope = context.initSafeStandardObjects();

So now i should have the possibility to be able to retrieve the javascript object. But how?

Script function = context.compileString("Any javascriptfunction as String", "javaScriptFile.js", 1, null);
function.exec(context, defaultScope);

But what would that javascript function look like to get that object as JSON (something like cars.stringify() )? And further more is that the right approach in using this function? And finally how and where to i save the object in a java Object?

i have already checked this post and this post also this post but all dont fit my criteria or are missing out on a code example for clarification

Edit: I have found another approach in calling/writing a javascript function in java as a string like:

Scriptable scriptObject;
private String functionAsString = "function getAsJson() {var objectString = { colour: \"silver\", drivemode: \"alldrive\" };return JSON.stringify(objectString);}";
Function fct = context.compileFunction(defaultScope, functionAsString, "AnyName", 1, null);
Object result = fct.call(context, defaultScope, scriptObject, null);

The only problem still standing is how do it get "objectString" to contain my cars.js? There somehow has to be a possibility to load that object in this variable

probably something like:

String functionAsString2 = "get cars() {return this.cars;}";

But how/and where do i specify the file in which to use this function?

Nostra
  • 53
  • 1
  • 8
  • one way is to call java code from your javascript file. eg execute the function fetchCar() in the javascript function, and make fetchCar() call a setter in java that sets the value. you would importPackage your java class into the script. (not clean I know) – CausingUnderflowsEverywhere Jan 29 '20 at 13:58
  • But I did a little research, maybe this answer is what you need: https://stackoverflow.com/a/18564532/4425643 – CausingUnderflowsEverywhere Jan 29 '20 at 13:59
  • @CausingUnderflowsEverywhere Thanks for the research! i knew i missed something. Ive already checked that post, and theoretically it's what im looking for but im missing the code example of how it works. because currently I'm not really understanding on how it should work. And mostly i would love to have all the code in Java and not having to write an additional javascript file. – Nostra Jan 29 '20 at 14:06
  • Also question, is there a reason you're using rhino and not the new script engine called nashorn? – CausingUnderflowsEverywhere Jan 29 '20 at 21:22
  • I seem to have found how to do it using nashorn, The person who asked the question has some simple code in his main method. https://stackoverflow.com/questions/28470828/how-to-use-nashorn-how-it-improve-performance It will just need a getter function in the javascript. – CausingUnderflowsEverywhere Jan 29 '20 at 21:25
  • @CausingUnderflowsEverywhere you're right. Nashorn seems like a good way to go. But ive read thrrough several articles about nashorn not beeing included in further JDK Versions. Therefore it would be sad if i would have to redo it over again in the future. The link you provided has some interesting ideas but all i really need is JSON.stringify(cars); without having to write and extra javascript function. But you gave me a good idea that im going to test now! – Nostra Jan 30 '20 at 09:11
  • Hmm they are deprecating the nashorn package, but not the java.scriptx API. hopefully when they remove it, someone else will re-implement a javascript engine for the API. https://docs.oracle.com/en/java/javase/11/docs/api/jdk.scripting.nashorn/module-summary.html – CausingUnderflowsEverywhere Jan 31 '20 at 04:50
  • Perhaps you are correct in choosing to use Rhino. I didn't know about the deprecation. Rhino is still actively developed with the latest release being 17 days ago. – CausingUnderflowsEverywhere Jan 31 '20 at 04:54
  • @CausingUnderflowsEverywhere i have found this link: https://stackoverflow.com/questions/3995897/rhino-how-to-call-js-function-from-java now the only thing standing in my way is to load that object from cars.js into a variable (see in the edited post) Any ideas on how to do that? – Nostra Jan 31 '20 at 07:45
  • @CausingUnderflowsEverywhere i found an answer that is working for my usecase. Hopefully this may help other people. Maybe you can check if the answer i provided is answering the question or should be edited for clarification. Otherwise ill close this topic. Thanks again for your help! – Nostra Feb 03 '20 at 11:53

1 Answers1

1

I have found a way to retrieve the object by using the ScriptEngine from Rhino

private ScriptEngineManager manager = new ScriptEngineManager();
private ScriptEngine engine = manager.getEngineByName("JavaScript");

engine.eval(Files.newBufferReader("PATH TO THE JAVASCRIPT FILE", StandardCharsets.UTF_8));

Object result = engine.get("cars"); //Variable in the javascript File

if(result instanceof Map){
result = (Map<String,Object>) result;
}

so the object is retrieved and can be accessed and casted as a Map> and recursively accesed to in the end having a java Object of the JavaScript Object. No need to use functions

Nostra
  • 53
  • 1
  • 8