Link to home
Start Free TrialLog in
Avatar of sidwelle
sidwelleFlag for United States of America

asked on

rhino JavaScript import, load

I have a JavaScript that I want to load into another JavaScript at execution.  I have done some searching and found that some options are available like "Load" or "Import" but no real examples.

so basically I have a hand full of functions in a file and I want to include them in my script w/some type of "include" statement like an script in a an Html script would do, but I in a Rhino implementation and not in a browser.

Any help is appreciated.
Thanks
Avatar of leakim971
leakim971
Flag of Guadeloupe image

why not copy/paste ?
Avatar of sidwelle

ASKER

What if I want to reference it from several other scripts ?
it was a proposition, I don't use Rhino and not sure why it's not well documented.
I think you can use the Rhino's load() documented, based on your requirement you can load as file or URL.

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/Shell

here is the programatical way of loading the javascript

http://www.java2s.com/Code/Java/JDK-6/UseanexternalfilecontainingthejavascriptcodeTheJSfileisloadedfromtheclasspath.htm
I have seen this before, but it looks like both examples use a shell and eval a the script, I want to just reference the script and use its functions like they were part of the main script.

Thanks
try this :
    var str = "";
    str = str + new String(org.apache.tools.ant.util.FileUtils.readFully(new java.io.FileReader("/path/to/your/file.js")));
    eval(str); // run the script, i think eval in your context are also very dangerous as if someone change file.js to do something bad...

Open in new window

I have seen some examples of the "require" or "import" command, but I can't seem to get the syntax correct ?
And w/o documentation, its pretty rough !
>>  I want to just reference the script and use its functions like they were part of the main script

best to merge the JS files that way you can access them in same scope.

If you see the example

http://www.java2s.com/Code/Java/JDK-6/UseanexternalfilecontainingthejavascriptcodeTheJSfileisloadedfromtheclasspath.htm

It shows how to invoke functions of the javascript file.

Better show a code snippet of what you are trying to do, so that we can help you better.
var f2 = "D:\\Projects\\dataMapper\\Test01.js";

java.lang.System.require(f2);  //this errors, function or prop not found.
import(f2);                                  //this cmd give a syntax error.
Both of these lines are incorrect:

java.lang.System.require(f2);  //Java System doesn't have a require() method defined!
import(f2);                                  //import what? and from where? no namespace nothing is in place.

Do you have a basic working example before addressing your import of other java-script file?
this cmd:
java.lang.System.load(f2);

Produces the following error:
java.lang.UnsatisfiedLinkError: D:\Projects\dataMapper\Test01.js: %1 is not a valid Win32 application
Sidwelle,

Load has a different purpose, it's usually meant for Java Native Interface. It's not for Javascript, You said you are using Rhino, I see no reference to Rhino in your current examples.

check:
 http://www.inonit.com/cygwin/jni/helloWorld/load.html
I am using a product that has implemented Rhino as a method to allow end users to create scripts to modify data as it passes through the application.

So, from reading far beyond the application, I have figured out that the app developers have implemented a method to allow users to create small script-lets using JavaScript syntax .  I assume that these scripts are executed via the 'eval' cmd in java.

What I want to do is be able to have a few text files of reusable functions/classes that I can attach to each script.

If "Load" is the wrong command for javaScript, what is the correct command ?
Here is an example of a reusable javaScript code module:
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Using
Maybe getting closer, this cmd:
java.lang.System.load("resource:"+f2);

Produces:
Expecting an absolute path of the library: resource:D:\Projects\dataMapper\Test01.js
The following worked for me :

	var engine = new Packages.javax.script.ScriptEngineManager().getEngineByName("JavaScript");
	engine.eval(new java.io.FileReader("test.js"));

Open in new window

Yeah, but what does it do ?  evaluates a script and returns a value ?  How is that going to allow me to use the modules and functions from my script ?
I have a feeling the "java.lang.System.load(... " command would probably work if I could figure out how to make the cmd look for files on the local drives ?
Maybe load will work, but the second challenge is about the scope...

The script I ran :
var engine = new Packages.javax.script.ScriptEngineManager().getEngineByName("rhino");
//print("type of engine is: " + (typeof engine) + "\n");
engine.eval(new java.io.FileReader("test.js"));
var invocable = new javax.script.Invocable(engine);
//print("type of invocable.invokeFunction is: " + (typeof invocable.invokeFunction) + "\n");
//print(invocable.invokeFunction.toString());
var obj = [ "Hello World!" ];
var result = invocable.invokeFunction("printToConsole", obj);
print("result is: " + result + "\n");

Open in new window


and here test.js :

function printToConsole(what) {
	print(what + "\n");
	return "Yes we did it!"
}
print("done\n\n");

Open in new window


Output:

MBP-de-leakim:Downloads leakim$ java -cp .:rhino-1.7.7.1.jar Shell test2.js
done

Hello World!
result is: Yes we did it!

MBP-de-leakim:Downloads leakim$ 

Open in new window

I am impressed that does work,  doesn't do exactly what I wanted.    

If the code in module creates a class, how would I access it members or methods.  I assumed that once it returns a result the module is destroyed ?
which module do you want to use inside your script? it's a proprietary module ? have you hand on this script to change it ?
or are you looking for a generic way ?
it's a proprietary module ? Yes
have you hand on this script to change it ?  Yes
are you looking for a generic way ?   Yes
ok, if you're able to create a string version of this module, just return this string an use eval.
var str = invocable.invokeFunction("getModuleAsString",[]);
eval(str);
ASKER CERTIFIED SOLUTION
Avatar of leakim971
leakim971
Flag of Guadeloupe image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
tested, that work fine, just need to use :
eval(""+str);
instead :
eval(str);
Your script worked, I was just disappointed that there was not a cleaner method.
I did find the command, it is "require", but it looks like it was only implemented in the newer versions of the product.  what I am working w/ is about 1 year old now.
I don't know if I can get it to work w/what I have or not.

Thank You.