Use a jar in JavaScript through Java ScriptEngine

2019-06-15 03:56发布

问题:

I need to use classes from a jar file inside JavaScript. I'm using JavaScript through Java ScriptEngine and would like to do something similar to what I did with Jython here,

    import org.python.core.Py;
    import org.python.core.PySystemState;
    ...
    PySystemState engineSys = new PySystemState();
    engineSys.path.append(Py.newString("C:/GMSEC_API/bin/gmsecapi.jar"));
    Py.setSystemState(engineSys);
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");

When I do this with Jython it works fine and the python files can use the api classes that are inside the jar file.

回答1:

I am able to use the jar's classes within JavaScript this way, but you have to set the jar to the class path when you go to run it. I was after a solution similar to Jython/Python's where you're able to set the jar inside Java but I'm just going to create batch files and sh files and set it that way (seems easier to do it that way now). Here is my solution that works for me.

To Compile Then Run:

    cd C:\your\directory\folder\with\the\javascript\and\java\files

    javac -d . ClassSpy.java FileSearch.java HelloWorld.java Main.java Parameters.java Run.java

    java -cp ./;C:\ABCAPI\bin\abcapi.jar hammer.main.Main gui=true input=JavaScriptStatus.js

Comments on the above lines:

  • when compiling you can use -d . if you have your java files as packages that you defined and it'll put them in folders with your package name. If that's not clear just check out this post (I'm getting off task) How to compile packages in java? .

  • Another note is that when I ran it I added two things to my class path -cp stands for class path and anything after that will be added to your class path for this current run. You can separate them with a semicolon. ./ adds the current directory to the class path and the rest I added after that was the location of the API's jar file I needed.

  • hammer.main is the package location of the class Main which is the class containing my main function to start the program.

  • The two arguments after that are specific to my program and you can see the JavaScript file I'm going to tell Java ScriptEngine to read and execute.

To Use The Jar File Inside JavaScript:

Now that the jar file is on the class path and visible we can get a package from inside that jar file then call the classes from the package. So for the example below abc.foo.pack.name is a package inside of abcapi.jar and the two classes I'm using ClassFromTheJarFile and AnotherClassFromTheJarFile are in that package. I'm using a technique of setting the package to a variable then prefixing the classes I want to use with the variable containing the package. Another way is to say importPackage(com.foo.bar) then you wont have to prefix the classes every time you instantiate them but this technique doesn't work for me for some reason (perhaps I did something wrong though). At any rate the following code works fine for me,

    myvariable = Packages.abc.foo.pack.name;

    var foo = new myvariable.ClassFromTheJarFile("arg1","arg2");

    foo.doSomething();

    var fooSister = new myvariable.AnotherCLassFromTheJarFile("arg1");

    fooSister.doSomthingFromThisClass();

Conclusion:

It turns out my mistake was trying to import the class directly like this,

    myvariable = Packages.abc.foo.pack.name.ClassFromTheJarFile;

Then I tried using it like,

    var foo = new myvariable.ClassFromTheJarFile("arg1","arg2");

Which wasn't working.

I hope this helps someone because I was getting a lot of remarks like, "You know Java and JavaScript are two different things right". Well yes I do know that, what is your point?

Keep In Mind:

I am not using this in a browser or over the internet. I am using this through Java ScriptEngine. If you need to get the jar file from a URL this link I found might help you http://mozilla-firefox-extension-dev.blogspot.com/2004/11/calling-java-code-in-custom-jars-from.html