Am using Nashorn script engine in java for evaluating expressions,
the below code for log works,
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("noshorn");
engine.eval("Math.log(99);");
whereas for log10 fails,
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("noshorn");
engine.eval("Math.log10(99);");
it throws an exception saying,
Caused by: <eval>:1 TypeError: Cannot call undefined
How can i resolve this.Please help.
The Math that is initialized by default not the java system Math. If you want the java's Math use:
var JavaMath = Java.type("java.lang.Math");
Then you can use all of the math methods. I am surprised Nashorn doesn't provide the javascript Math Object, which would have log10.
Nashorns current Math implementation is based on this version of the standard which does not yet contain Math.log10.
#matt has already given a workaround (+1), here is another one
engine.eval("java.lang.Math.log10(99);");
Math.log10 is from ECMAScript6 -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 , http://www.ecma-international.org/ecma-262/6.0/#sec-math.log10
Nashorn as of jdk8u implements ECMAScript 5.1. (few) Elements of ES6 being added to jdk9.
Related
I am trying python and java integration using Jep. I have loaded randomforest model from pickle file (rf.pkl) as sklearn.ensemble.forest.RandomForestClassifier object from java program using Jep.
I want this loading to be one time so that I wanted to execute a python function defined in python script prediction.py (to predict using rf model) by sending "rfmodel" argument from java to call python function.
But the argument sent to python from java is read as string in python. How can I retain the datatype of argument in python as sklearn.ensemble.forest.RandomForestClassifier?
Jep jep = new Jep();
jep.eval("import pickle");
jep.eval("clf = pickle.load(open('C:/Downloads/DSRFmodel.pkl', 'rb'))");
jep.eval("print(type(clf))");
Object randomForest = jep.getValue("clf");
jep.eval("import integration");
jep.set("arg1", requestId);
jep.set("arg2", randomForest);
jep.eval("result = integration.trainmodel(arg1, arg2)");
------------
python.py
import pickle
def trainmodel(requestid, rf):
//when rf is printed it is 'str' format.
When Jep converts a Python object into a Java object if it does not recognize the Python type it will return the String representation of the Python object, see this bug for discussion on that behavior. If you are running the latest version of Jep(3.8) you can override this behavior by passing a Java class to the getValue function. The PyObject class was created to serve as a generic wrapper around arbitrary python objects. The following code should do what you want:
Jep jep = new Jep();
jep.eval("import pickle");
jep.eval("clf = pickle.load(open('C:/Downloads/DSRFmodel.pkl', 'rb'))");
jep.eval("print(type(clf))");
Object randomForest = jep.getValue("clf", PyObject.class);
jep.eval("import integration");
jep.set("arg1", requestId);
jep.set("arg2", randomForest);
jep.eval("result = integration.trainmodel(arg1, arg2)");
I'm trying to check velocity scripting engine 2.0 which Provide JSR 223 implementation and support of Compilable
the Compilable interface has been implemented in the process.
I use jars: velocity-engine-scripting-2.0.jar, velocity-1.7.jar, commons-collections-3.2.2.jar
from previous answer I use the following code
//class org.apache.velocity.script.VelocityScriptEngine
final ScriptEngine engine = engineFactory.getScriptEngine();
if (engine instanceof Compilable) {
try {
((Compilable) engine).compile("");
...
For velocity I get the following:
javax.script.ScriptException: org.apache.velocity.exception.ResourceNotFoundException: No template name provided
at org.apache.velocity.script.VelocityScriptEngine.compile(VelocityScriptEngine.java:311)
at org.apache.velocity.script.VelocityScriptEngine.compile(VelocityScriptEngine.java:288)
at com.Workers.LevelCheck.main(LevelCheck.java:69)
Caused by: org.apache.velocity.exception.ResourceNotFoundException: No template name provided
at org.apache.velocity.runtime.resource.loader.StringResourceLoader.getResourceStream(StringResourceLoader.java:353)
at org.apache.velocity.Template.process(Template.java:108)
at org.apache.velocity.script.VelocityScriptEngine.compile(VelocityScriptEngine.java:306)
... 2 more
Also when I tried to give template name ((Compilable) engine).compile("v.vm"); it failed with same exception
You cannot use velocity-engine-scripting-2.0.jar with velocity-1.7.jar, you need to use velocity-engine-core-2.0.jar otherwise you'll get unpredictable results.
JSONata is an expression language designed to query and transform JSON data structures.
I find that current implementations of JSONata are in Javascript only. (https://github.com/jsonata-js/jsonata)
I want to use JSONata in my Java code. It'll make life much easier to manipulate JSON documents in Java.
A possible way could be to use the standard Java classes under javax.script package to interact with the Javascript-based JSONata implementation.
Has anyone already done this? Is there any sample code to demonstrate how this can be achieved?
Has anyone implemented other mechanisms of using JSONata in Java?
The following snippet shows how you could invoke the JSONata processor from Java using the embedded JavaScript engine...
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
Invocable inv = (Invocable) engine;
FileReader jsonata = new FileReader("jsonata.js");
// load the JSONata processor
engine.eval(jsonata);
// read and JSON.parse the input data
byte[] sample = Files.readAllBytes(Paths.get("sample.json"));
engine.put("input", new String(sample));
Object inputjson = engine.eval("JSON.parse(input);");
// query the data
String expression = "$sum(Account.Order.Product.(Price * Quantity))"; // JSONata expression
Object expr = inv.invokeFunction("jsonata", expression);
Object resultjson = inv.invokeMethod(expr, "evaluate", inputjson);
// JSON.stringify the result
engine.put("resultjson", resultjson);
Object result = engine.eval("JSON.stringify(resultjson);");
System.out.println(result);
In this example, the jsonata.js file has been pulled down from the JSONata GitHub repo as well as the 'Invoice' sample code from try.jsonata.org.
Extra code would be needed to handle errors, but this gives the general idea.
I have just posted a Java implementation of JSONata called JSONata4Java.
maven central:
JSONata4Java jar files are located here in Maven Central: https://search.maven.org/search?q=g:com.ibm.jsonata4java
pom.xml dependency
<dependency>
<groupId>com.ibm.jsonata4java</groupId>
<artifactId>JSONata4Java</artifactId>
<version>1.0.0</version>
</dependency>
github:
The Java port of jsonata project named JSONata4Java has been posted here: https://github.com/IBM/JSONata4Java
If you would like to contribute, please print and sign the appropriate JSONata4Java cla document and mail it to me:
IBM Corporation
c/o Nathaniel Mills
16 Deer Hill Ln.
Coventry, CT, 06238, US
Attn: OSS CLA Processing
Thanks in advance.
You can use the JSONata-Java project:
https://github.com/cow-co/jsonata-java
A Java port of the original (JavaScript) interpreter for the JSONata
JSON query and transformation language.
Executing the following code in Java7
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("js");
Bindings b = scriptEngine.createBindings();
b.put("x", true);
scriptEngine.eval("x&y", b);
I get the error
sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "b" is not defined. (<Unknown Source>#1) in <Unknown Source> at line number 1
Is there an option to evaluate to null/false for undefined objects, like in JavaScript?
I know that an option will be to do something like "this.x&this.y" instead of "x&y", but I don't have control over that string (user entered).
I browsed a little bit through the Rhino code and it seems that there's no such option.
In the end I will append "this." in front of each variable. This is not by far a desirable solution (I will not even accept my own answer :) ), but for the time being I have no other.
I'm trying to calculate high-PMI terms for a particular token in pylucene. A colleague gave me some Java code that works, but I am having trouble translating it into Python. In particular, the code relies on a custom collector. Here's the initial query code:
def __init__(self, some_token, searcher, analyzer):
super(PMICalculator, self).__init__()
self.searcher = searcher
self.analyzer = analyzer
self.escaped_token = QueryParser.escape(some_token)
self.query = QueryParser("text",self.analyzer).parse(self.escaped_token)
self.term_count_collector = TermCountCollector(searcher)
self.searcher.search(self.query, self.term_count_collector)
self.terms = self.term_count_collector.getTerms()
Here's the Term Count Collector class: http://snipt.org/vgGi8
This code breaks at self.searcher.search with the error:
File <filename>, line 26, in __init__
self.searcher.search(self.query, self.term_count_collector)
lucene.JavaError: org.apache.jcc.PythonException: collect() takes exactly 2 arguments (3 given)
TypeError: collect() takes exactly 2 arguments (3 given)
Java stacktrace:
org.apache.jcc.PythonException: collect() takes exactly 2 arguments (3 given)
TypeError: collect() takes exactly 2 arguments (3 given)
at org.apache.pylucene.search.PythonHitCollector.collect(Native Method)
at org.apache.lucene.search.HitCollectorWrapper.collect(HitCollectorWrapper.java:46)
at org.apache.lucene.search.TermScorer.score(TermScorer.java:86)
at org.apache.lucene.search.TermScorer.score(TermScorer.java:74)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:252)
at org.apache.lucene.search.Searcher.search(Searcher.java:110)
I did some google searching, but to no avail - I am new at lucene, and can't tell if this is just not a feature that's supported by 2.9.4, or if it's a pylucene issue, or if my code is wrong. Please help!