readFully not defined with Java Nashorn Javascript Engine - java

I am trying to run a javascript script with the new Java 8 Nashorn javascript engine but it fails with the following error:
<eval>:1 ReferenceError: "readFully" is not defined
The script uses the readFully function that should be defined in the global scope nashorn is run with the scripting mode enabled (wich is default when running through a ScriptEngine as seen here http://mail.openjdk.java.net/pipermail/nashorn-dev/2013-December/002562.html).
Here is a sample to reproduce the error:
import java.io.FileNotFoundException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Test {
public static void main(String[] argv) throws FileNotFoundException, ScriptException {
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
scriptEngine.eval("print('Hey!');print(print);print(readFully);");
}
}
This sample prints Hey ! and then the source code of the print function (another nashorn built-in function) and finally it should print the source code of the readFully method. But I have this Exception instead:
Exception in thread "main" javax.script.ScriptException: ReferenceError: "readFully" is not defined in <eval> at line number 1
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:586)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:570)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:525)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:521)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:192)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at com.github.bringking.maven.requirejs.Test.main(Test.java:14)
Caused by: <eval>:1 ReferenceError: "readFully" is not defined
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:58)
at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:320)
at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:292)
at jdk.nashorn.api.scripting.NashornScriptEngine.__noSuchProperty__(NashornScriptEngine.java:272)
at jdk.nashorn.internal.scripts.Script$engine.L:35(nashorn:engine/resources/engine.js:37)
at jdk.nashorn.internal.scripts.Script$\^eval\_.runScript(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:568)
... 5 more
When the sample script is run with the nashorn command line with the -scripting parameter (with the jjs tool of the jdk), all is fine. Here is the result of the same script:
Hey!
function print() { [native code] }
function readFully() { [native code] }
I could rewrite a readFully method and bind it with the script context, but I prefer to understand why it does not work and use already built-in functions.
Regards

Finally, I have implemented a readFully function that I use in my script (Only compatible with Nashorn):
function readFully(url) {
var result = "";
var imports = new JavaImporter(java.net, java.lang, java.io);
with (imports) {
var urlObj = null;
try {
urlObj = new URL(url);
} catch (e) {
// If the URL cannot be built, assume it is a file path.
urlObj = new URL(new File(url).toURI().toURL());
}
var reader = new BufferedReader(new InputStreamReader(urlObj.openStream()));
var line = reader.readLine();
while (line != null) {
result += line + "\n";
line = reader.readLine();
}
reader.close();
}
return result;
}

readFully is not a standard JavaScript function and it is likely not standard in Nashorn either.
There were similar issues when Rhino was chosen for inclusion in the Sun implementation of Java 6. The scripting tool may provide enhancements that are not present in the embedded API. readFully is not a documented function in the Java 8 Nashorn API.
In previous versions of Java the specification stated that provided scripting engines were an implementation detail of the JRE vendor. I am not aware if Java 8 makes anything about the engines provided mandatory or whether it makes any future compatibility guarantees. I would check JSR-337 thoroughly if this was likely to be an issue.

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions
readFully (-scripting mode only)
This function reads the entire contents of a file passed in as a string argument and sends it to stdout, or you can assign the result to a variable.
readFully example:
jjs> readFully("text.txt")
This is the contents of the text.txt file located in the current working directory.

readFully is enabled only in scripting mode. Nashorn docs
try this:
>>jjs -scripting
jjs> readFully("your_file")

readFully() function is only available as built in function in nashorgn when you enable scripting in you application
There are two ways you can do this:-
pass -Dnashorn.args=-scripting when you run your application to enable nashorn
scripting
Enable it programmatically by creating Nashorn engine with scripting args
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[] { "-scripting" });

Related

Is Jmeter Beanshell support invoke function from Kotlin jar file

I have Kotlin class:
class Ping {
fun ping(from: String): String{
return "Hello $from"
}
}
I've built jar file from this class. and included it to Jmeter and invoked it in BeanShell Sampler:
Ping ping = new Ping();
ping.ping("Jmeter");
it appear error Error invoking bsh method: eval Sourced file: inline evaluation of: ``Ping ping = new Ping(); ping.ping("Jmeter");'' : Method Invocation ping.ping
but I tried to change parameter of the method from string to int it work fine.
Any solution for this problem?
Thank you!
I cannot reproduce your issue using:
JMeter 5.4.1
Kotlin 1.5 (I copied the following .jars to JMeter Classpath just in case)
kotlin-reflect.jar
kotlin-reflect-sources.jar
kotlin-stdlib.jar
kotlin-stdlib-jdk7.jar
kotlin-stdlib-jdk7-sources.jar
kotlin-stdlib-jdk8.jar
kotlin-stdlib-jdk8-sources.jar
kotlin-stdlib-sources.jar
kotlin-test.jar
kotlin-test-sources.jar
The following sample code:
Ping ping = new Ping();
log.info(ping.ping("Jmeter"));
So double check your .jar file and JMeter Classpath. It also worth trying to put your code inside try block like
try {
Ping ping = new Ping();
log.info(ping.ping("Jmeter"));
}
catch (Exception ex) {
log.error("Beanshell failure", ex);
}
this way you will get the root cause of the problem in jmeter.log file
Also be aware that starting from JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting so maybe it worth considering migrating to Groovy, see Apache Groovy - Why and How You Should Use It article for more details, it might be the case you won't need any Kotlin code.

Run matlab function in java class in absence of matlab environment

I want to use matlab function in java application. I create java package from my function by deploytool in matlab. Now, how can i use this package? Can only import the jar file created by deploytool in my java project and use its function?
After a lot of googling, I used this toturial but in the final step, i get error "could not load file".
Also i read about MatlabControl, but in this solution, we should have matlab environment in our system to java code running. But i will run my final app in systems that may not have matlab at all.
So i need a solution to run matlab function in java class even in absence of matlab environment.
Finally I solve my problem. the solution step by step is as follows:
write matlab function:
function y = makesqr(x)
y = magic(x);
Use deploytool in matlab and create java package.
3.create new java application in Eclipse and add main class. import javabuilde.jar and makesqr.jar:
import com.mathworks.toolbox.javabuilder.MWArray;
import com.mathworks.toolbox.javabuilder.MWClassID;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import makesqr.Class1;
and main.java:
public class main {
public static void main(String[] args) {
MWNumericArray n = null;
Object[] result = null;
Class1 theMagic = null;
try
{
n = new MWNumericArray(Double.valueOf(5),MWClassID.DOUBLE);
theMagic = new Class1();
result = theMagic.makesqr(1, n);
System.out.println(result[0]);
}
catch (Exception e)
{
System.out.println("Exception: " + e.toString());
}
finally
{
MWArray.disposeArray(n);
MWArray.disposeArray(result);
theMagic.dispose();
}
}
}
add javabuilder.jar and makesqr.jar to java build path of your project.
run it.
the Double.valueOf(3), define the input for our function and the output is as follows:
8 1 6
3 5 7
4 9 2
I didn't get properly your problem. Did you already compile the jar file from Matlab code and you are trying to use that, or you are at the last step of the tutorial?
If your answer is the latest case, most probably you forgot the "." before the class path.
From tutorial you linked:
You must be sure to place a dot (.) in the first position of the class path. If it not, you get a message stating that Java cannot load the class.
Also check if the matlab compiler path ("c:\Program Files\MATLAB\MATLAB Compiler Runtime\v82\toolbox\javabuilder\jar\javabuilder.jar" - in the tutorial) is correct for your system.

Jpype passing arguments to Java

I have a java programmer with following line
service.loadPropertiesForItems(Inbox, new PropertySet(ItemSchema.Subject, ItemSchema.Body));
Program calls classes and methods from external jars.
I want to write equivalent code in python which calls external jars like my java program does.
Using Jpype I implemented the code but it fails on following line
service.loadPropertiesForItems(inbox, ewsPkg.PropertySet(ewsPkg.ItemSchema.Subject, ewsPkg.ItemSchema.Body))
Here PropertySet, ItemSchema are classes which I use from external jar.
ItemSchema.Subject and ewsPkg.ItemSchema.Body are class type
Running the code I get following error on line mentioned above -
service.loadPropertiesForItems(inbox, ewsPkg.PropertySet(ewsPkg.ItemSchema.Subject, ewsPkg.ItemSchema.Body))
File "C:\Python27\lib\site-packages\jpype\_jclass.py", line 79, in _javaInit
self.__javaobject__ = self.__class__.__javaclass__.newClassInstance(*args)
RuntimeError: No matching overloads found. at src/native/common/jp_method.cpp:121
Thanks
As suggested by Martin https://github.com/originell/jpype/issues/117
following code works well
ItemSchema = ewsPkg.ItemSchema
PropertyDefinition = ewsPkg.PropertyDefinition
Subject = ItemSchema.Subject
Body = ItemSchema.Body
args = JArray(PropertyDefinition)([ItemSchema.Subject, Body])
PropertySet = ewsPkg.PropertySet(args)

ReferenceError: "alert" is not defined

I am trying to call a java script function from java code.
Here is my Java code
public static void main(String[] args) throws FileNotFoundException {
try {
/**
* To call a anonymous function from java script file
*/
ScriptEngine engine = new ScriptEngineManager()
.getEngineByName("javascript");
FileReader fr = new FileReader("src/js/MySpec.js");
engine.eval(fr);
} catch (ScriptException scrEx) {
scrEx.printStackTrace();
}
}
Here is my java script file:
(function() {
alert("Hello World !!!");
})();
But when I run main method of driver class it is giving me error as below:
Exception in thread "main" javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "alert" is not defined. (<Unknown source>#2) in <Unknown source> at line number 2
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:110)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:232)
at Java6RhinoRunner.load(Java6RhinoRunner.java:42)
at Java6RhinoRunner.main(Java6RhinoRunner.java:12)
What I know is that it need some script engine to execute it.
For that I added rhino.jar file in to my class path.But this is not working.
I an not getting how to solve this error.
Please help.Thanks in advance.
alert is not part of JavaScript, it's part of the window object provided by web browsers. So it doesn't exist in the context you're trying to use it in. (This is also true of setInterval, setTimeout, and other timer-related stuff, FYI.)
If you just want to do simple console output, Rhino provides a print function to your script, so you could replace alert with print. Your script also has access to all of the Java classes and such, so for instance java.lang.System.out.println('Hello'); would work from your JavaScript script (although it's a bit redundant with the provided print function). You can also make Java variables available to your script easily via ScriptEngine.put, e.g:
engine.put("out", System.out);
...and then in your script:
out.println('Hello from JavaScript');
...so that's a third way to do output from the script. :-)
See the discussion in the javax.script package documentation, in particular ScriptEngine#put, or for more complex cases, Bindings (and SimpleBindings) and ScriptContext.

Why does Jython not find this module? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to run a python script from java?
I am running a Python script using Jython and got this error:
Exception in thread "main" Traceback (innermost last): File "C:\Facebook\LoginPython\Facebook.py", line 5, in ? ImportError: no module named cookielib
Why doesn't this work?
A little bit more about using Jython - had my share of problems with that as well. Note that this may not be the best way to do it, but it works fine for me.
I assume you want to call a function foo in module bar from your Java code that takes a string argument and returns a string:
PythonInterpreter interpreter = new PythonInterpreter();
// Append directory containing module to python search path and import it
interpreter.exec("import sys\n" + "sys.path.append(pathToModule)\n" +
"from bar import foo");
PyObject meth = interpreter.get("foo");
PyObject result = meth.__call__(new PyString("Test!"));
String real_result = (String) result.__tojava__(String.class);
The sys.path.append() part is only necessary if your module isn't part of the Python search path by default, which may very well be the problem if you get Import or Module not find errors.
Also you need to cast the objects between the java and python versions, you'll need to look that up if necessary, so far I only needed primitive types that were easy to cast, not sure if it's as easy for arbitrary java objects.
Use Jython to run Python on the JVM. Use PyDev to develop with Python (or Jython) on Eclipse.

Categories