Use a jar in JavaScript through Java ScriptEngine - java

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.

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

Related

ImportError when Importing Python Module into Java Program in Eclipse

I have written a simple function in python that I want executed by Jython's PythonInterpreter. The problem is, I'm not sure where the .py class needs to go.
I have tried in the same package as the Java class, the same working directory as well as another folder.
Importing files from different folder
I am interested in the above method, but I do not want to use an absolute path as I intend to make this program available for other people to use.
Here is my workspace layout:
I will be invoking the function in myscraper.py from EntryManagement.java. The function is defined as follows:
def validateUrl(url):
try:
uReq(url)
return(1)
except URLError:
return(0)
How do I do this?
Used OS to get the current working directory and worked from there, using sys.path
interpreter.exec("sys.path.insert(0, os.getcwd() + '\\src\\python')");
interpreter.exec("from myscraper import validateUrl");

How does Javac work for multiple files, directories, classes and source?

I'm trying to figure out how javac works with regard to stuff like sourcepath, classpath and prebuilt classes etc. I'm trying to read the documentation, but can't really make sense of it.
I've tried to think of some sample cases below.
If I'm compiling a single file onlyfile.java which has no dependencies, which has 2 classes A and B , and class A uses class B , does class B need to be defined/declared before A ? Or is javac smart and does multiple passes or something like that ?
root.java uses another class in a file file2.java located in the same folder. If I execute javac root.java , how does javac know to search the folder for the class file and if not found , for source file instead ?
How does the above work if the file2 is located in a subdirectory ?
EDIT:
I read somewhere that import is just a way to cut down on typing rather than "loading" anything like in python.
Suppose that I'm building only 1 java file which uses multiple other classes, and that these class files already exist. Without import, the a.b.c.d part of the class object already tells me where to search for the class file, then why a cp option ?
1) If you compile class A which uses class B then class B will be compelled as well. If you compile class B (which is used inside A, but A is not used inside B), class A will not be compelled. Find more details end examples here.
2) javac searches inside source-path and class-path. If you run javac without arguments like javac A.java it sets classpath and sourcepath to current directory. If requested class is not found neither in classpath nor in sourcepath you'll have compilation error.
3) Java has strict rules for project structure. You can't simply place source file to another folder without updating file content.
Every folder in the project should have folder hierarchy with respect of package declaration.
Definition: A package is a grouping of related types providing access protection and name space management.
for instance if you have class A.java with package declaration like this
package com.mycompany;
The corresponding folder structure should look like this:
com/mycompany/A.java
If you follow this rules compiler will be able to resolve dependencies just like I explained in #1. Find more information here.
For first two options try with javac *.java
Duplicate of Compiling Multiple Classes (Console) in Java

Use class path properly in Java in command line

I'm newbie to Java. I have read all the documentations regarding specifing the classpath. But I'm still confused about my case. I'm trying to use the BuildIndex command that is part of semantic package, specifically this example,
java pitt.search.semanticvectors.BuildIndex -luceneindexpath $INDEX_MADE_ABOVE.
in here
The source of how to use the class is here https://github.com/semanticvectors/semanticvectors/wiki/InstallationInstructions#to-build-and-search-a-model
I'm trying to specify the classpath like:
java cp- {classpath} pitt.search.semanticvectors.BuildIndex -luceneindexpath $INDEX_MADE_ABOVE.
in here
But I'm not sure what the class path should be here. . The command line should have a class path, but thinking it should not be related to my project, it's part of the semantic vectors package. Do I need to clone that? its source code from the package here https://github.com/semanticvectors/semanticvectors/blob/master/src/main/java/pitt/search/semanticvectors/BuildIndex.java..
My trials was using the path of my project as the picture but didn't work. Another trial was using -jar jarName ,, got the same error: Could not find or load main class pitt.search.semanticvectors.BuildIndex. I appreciate the help as I'm confused and new to this.
In Java, classpath is the path pointing to either the directory or the jar file where your compiled java class files are located.
In your project, the class pitt.search.semanticvectors.BuildIndex is located in the jar file C:\Users\{yourusername}\Downloads\semanticvectors-5.8.jar. Therefore, the classpath is C:\Users\{yourusername}\Downloads\semanticvectors-5.8.jar.
Try something like
java -cp C:\Users\{yourusername}\Downloads\semanticvectors-5.8.jar pitt.search.semanticvectors.BuildIndex -luceneindexpath $INDEX_MADE_ABOVE
I think you mistyped cp- instead of -cp.
For more details how to use classpath, please refer to Java SE Documentation

Mac Terminal: Could not find or load main class CLASSNAME

I am trying to run a java program through the Terminal on Mac, yet getting:
Error: Could not find or load main class (MY CLASSNAME)
I compiled this application with Eclipse, and when I run this with Eclipse, it works fine.
Furthermore, I am in the right directory, as when I type "ls" in the Terminal, it lists all the files, includes the class file I am trying to run.
This is what I type:
java mainClass
I would very much appreciate help to solve this!
Thank you,
Dean
EDIT: Solution - instead of java mainClass, it must have package too: java startPackage.mainClass
Start by making sure you are at the directory above the top level package
If the class belongs to the package com.foo.bar, you want to be in the directory above com.
In your case, you want to be in the directory above startPack.
Then you need to use the fully qualified name to run the class...
java statPack.mainClass
For example...
Make sure you have the current directory inside your CLASSPATH.
java -cp . mainClass
To set this globally, you can use export CLASSPATH=$CLASSPATH:. inside .bash_profile.
Separately, if your class lives inside a package such as com.foo.bar, then you will need to go to the parent directory of com and run your application with the full path.
java com.foo.bar.mainClass
I too faced this on Mac machine and then what I had to do to make it work was:
Problem Statement:
I had one package xyz under the root of project i.e src/main/java and then inside xyz package I had one class Student.java
my current directory is /Users/username/projectname/src/main/java/xyz:
I can see Student.java exists here
and I compiled it using javac Student.java
Now I see class file has been created at this location. But when I try to run the class file using java Student
I get the error: Error: Could not find or load main class Student
Solution:
Now the solution is to go one step back in the directory and go to root path:/Users/username/projectname/src/main/java and run the command
java xyz.Student
and it will work.
Link to follow: https://javarevisited.blogspot.com/2015/04/error-could-not-find-or-load-main-class-helloworld-java.html
For people dumb like me, make sure you are typing java HelloWorld - and NOT java HelloWorld.class - to run the compiled file with the name HelloWorld.class. This is especially so if you are used to hitting the tab key to complete the file name, as the terminal will give you java HelloWorld.class if you hit the tab key for autocomplete after typing something like java He...
This answer is here because it took 3 sites, including this answer, and 25 mintues before I figured out what I was doing wrong.
Logic is easy, typing is hard.
Using the absolute path can also resolve this problem:
java -classpath /Users/xingliu/IdeaProjects/springproject/src/main/java/ startPackage.mainClass

How can I load data files in a Jython module?

I have some Jython modules that I'm trying to make work from within a JAR. Everything is set up fine except that some modules expect to open files from the filesystem that are located in the same directory as the Python script itself. This doesn't work anymore because those files are now bundled into the JAR.
Basically I want to know if there's an equivalent of Class.getResourceAsStream() that I can use from within the Python code to load these data files. I tried to use '__pyclasspath__/path/to/module/data.txt' but it didn't exist.
In java Class.getResourceAsStream() uses java's class loading system to find a resource. Python's class loading mechanism is intended to provide some similar capabilities. Most of it is described here and in PEP 302.
A quick summary of this:
when a python module is loaded, it's loader should set the __loader__ attribute
a loader should support additional methods to get data from the same source
The default zipimporter, which is used when python classes are loaded from zip or jarfiles, luckily supports this methods. So if you know a data file is located in the same jar as a python module, you could use it's loader to load it:
import some_module
data = some_module.__loader__.get_data("path/in/archive/file.txt")
Maybe I'm just missing the point, but can't you use getResourceAsStream() on a Java class?
I had the same problem, however I am not certain my circumstances were exactly the same. I did not see the exception concerning the absence of get_data until I pushed my .jar to the web and tried to WebStart it, (WebStarting locally and starting my jar with java -jar worked fine).
Anyway, this is how I solved my problem:
import SomeClass
url = SomeClass.getClassLoader().findResource('path/to/resource.txt')
inputStream = url.openStream()
# ...
SomeClass is a Java class in my .jar file. It happens to be the Java class that I use to start the Jython interpreter, so I know it will always be there.

Categories