Jython and python modules - java

I've just started using the PythonInterpreter from within my Java classes, and it works great! However, if I try to include python modules (re, HTMLParser, etc.), I'm receiving the following exception (for re):
Exception in thread "main" Traceback (innermost last):
File "", line 1, in ?
ImportError: no module named re
How could I make the classes from the jython jar "see" the modules python has available?

You embed jython and you will use some Python-Modules somewere:
if you want to set the path (sys.path) in your Java-Code :
public void init() {
interp = new PythonInterpreter(null, new PySystemState());
PySystemState sys = Py.getSystemState();
sys.path.append(new PyString(rootPath));
sys.path.append(new PyString(modulesDir));
}
Py is in org.python.core.
rootPath and modulesDir is where YOU want !
let rootPath point where you located the standard-jython-lib
Have a look at src/org/python/util/PyServlet.java in the Jython-Source-Code for example

According to the FAQ:
4.1 What parts of the Python library are supported?
The good news is that Jython now supports a large majority of the standard Python library. The bad news is that this has moved so rapidly, it's hard to keep the documentation up to date.
Built-in modules (e.g. those that are written in C for CPython) are a different story. These would have to be ported to Java, or implemented with a JNI bridge in order to be used by Jython. Some built-in modules have been ported to JPython, most notably cStringIO, cPickle, struct, and binascii. It is unlikely that JNI modules will be included in Jython proper though.
If you want to use a standard Python module, just try importing it. If that works, you're probably all set. You can also do a dir() on the modules to check the list of functions it implements.
If there is some standard Python module that you have a real need for that doesn't work with Jython yet, please send us mail.
In other words, you can directly use Python modules from Jython, unless you're trying to use built-in modules, in which case you're stuck with whatever has been ported to Jython.

Check your jython sys.path . Make sure that the library you want to load are in this path.
Look at jython faq for more details.

You can refer here for the solution Importing python modules in jython
Download ez_setup.py from here http://peak.telecommunity.com/dist/ez_setup.py
Then run jython ez_setup.py <any module name>.
Running it on any folder path doesn't matter.
I could install pymysql with it, no problem.

Related

How do I build my java classes to not result in NoClassDefFoundException from JPype?

I have a Netbeans project of some Java code I wrote many years ago. I am doing a new project in python now, but I have a Java class in my old project that has some handy MIDI code that I would like to use since I have so far been unable to easily translate to python.
I used pip to install JPype, used Netbeans to build the class I need, and moved the .class file into the same directory as my python file. Here is an abridged part of my python code to call the Java class, which is called "SoundTester" and was in a package called "soundsynthesis".
from jpype import startJVM, shutdownJVM, java, addClassPath, JClass, JInt
import jpype.imports
startJVM(convertStrings=False)
try:
pass # Not sure why we need a pass here
tester = JClass('soundsynthesis/SoundTester')
except Exception as e:
print(f"Exception: {e}")
shutdownJVM()
The result is
Exception: java.lang.NoClassDefFoundError: soundsynthesis/SoundTester
Note that if I change soundsynthesis/SoundTester to just SoundTester, I get this slightly different exception:
Exception: java.lang.NoClassDefFoundError: SoundTester (wrong name: soundsynthesis/SoundTester)
I'm thinking that the issue may be due to me moving the .class files out of the Netbeans project and into my working directory, but I don't know how to resolve that. I also tried moving the java files into my desired directory and just using javac to build them.
I have ensured that my version of python and the jdk are both 64-bit, as that was a similar question's issue.
This is an issue with the path specification. It is true that JNI usually refers to classes using the slash notation. However, in this case JClass calls the Java Class.forName() method which requires dot notation rather than JNI. Thus the solution to this issue is to use JClass('soundsynthesis.SoundTester').
Here is an example using the test harness in jpype.
import jpype
jpype.startJVM(classpath=['test/classes'], convertStrings=False)
j = jpype.JClass('jpype.common.Fixture') # success
j = jpype.JClass('jpype/common/Fixture') # fails
In general, JPype uses the notations that are found in Java itself rather than those imposed by JNI. For further examples, please see the section "Import a class without tld" in the quick guide.
I solved the issue. Perhaps not the most elegant solution, but I modified the Java classes so they instead were not in any package (or rather they were in the default package) and then moved them to my python working directory and built them with javac there.
Once I had .class files of my java classes, I could call
tester = JClass('SoundTester') with no problem whatsoever.
Hope this helps someone else.

How to include a library in Java which in C++ with having native binding in Java (librets)?

I am stuck at importing a library which is originally written in C++, but has native binding for Java. Here is the library https://github.com/NationalAssociationOfRealtors/libRETS, and I was able to build it through the doc in doc/build, but what after that? I see some makefiles in project/build/ and I want to import this library in Java. Any help will be really appreciated as I cannot find anything in the documentation, all I know is there are some makefiles and the description claims that this library has native bindings for other languages.
Watch the output of ./configure carefully and make sure the build is configured to create the SWIG components (namely, for Java.)
Option summary:
Use ccache .................: no
Use dependency checking ....: no
Use -fPIC...................: yes
Use shared dependencies.....: yes
Compile type................: Normal
Compile examples............: no
Compile SQL compiler........: no
Compile SWIG bindings.......: no <-------- should say yes
With DotNet...............: no
With Java.................: no <--------- me too
With PERL.................: no
With PHP..................: no
With Python 2.............: no
With Python 3.............: no
With Ruby.................: no
With Node.js..............: no
Enable Maintainer Docs......: no
I tried it and a fairly recent version of SWIG was required -- more recent than were in my package manager. Without that, the SWIG bindings don't get built and there's no Java.
However, once you do get that build, it should be a fairly straightforward endeavor of calling into a jar file, as with any other Java project. Who knows, the build might even generate Javadoc for you so you have some idea of what to call.

How can I specify entry-point class and jar archive for JBCO (Java ByteCode Obfuscator)?

I can't guess how can I specify class, which is entry-point of my program (therefore shouldn't be obfuscated), and my jar archive. Please show me an command-line example, how to use JBCO when I have /home/example/myJar.jar and within it com.example.EntryPoint class and my external dependency /home/example/dependencies/dependencyJar.jar.
Also, please, does anybody know if this project is still alive and what jdk it supports?
A lot of time have passed, but recently I have passed across the java transformation frameworks and find out that JBCO now is a part of soot framework, hosted on GitHub, but it is #deprecated as for now. There is a wiki where you can get more info about how to use soot/jbco (if you still want to, on your own risk, even though JBCO is deprecated and not under active development it still from time to time accepts PRs from contributors).
As for the command line options it might be:
java -cp .:/home/example/sootclasses-trunk-jar-with-dependencies.jar soot.jbco.Main -process-dir /home/example/compiled -output-dir /home/example/obfuscated -soot-class-path .:/home/example/myJar.jar -output-format class -app -main-class com.example.EntryPoint -t:9:wjtp.jbco_cr
Soot can process your compiled code as class files (then pass it to -process-dir option) or as jar (then pass it as part of soot-class-path) - soot can process many forms of bytecode (java/scala/.. bytecode, android bytecode, jasmin, jimple). There are also options to specify what is library classes and application or argument classes more precisely, for more info please refer to soot's wiki page.

Equivalent of Java JAR files in Erlang

This is a completely newbie question from a Java programmer trying to learn Erlang. What's the equivalent of a Java JAR file in Erlang by which 3'rd party libraries can be included in an Erlang application?
The other day I made a copy of the mochijson2.erl in my project and it worked, but I am wondering if there's a better/more formal way of discovering and including libraries in the Erlang world.
If you're familiar with Maven (or its siblings), the Erlang analogue is Rebar.
You could create a rebar.config (similar to a POM file) with the contents
{deps, [
{mochiweb, "2.9.0", {git, "https://github.com/mochi/mochiweb.git", {tag, "v2.9.0"}}}
]}.
Then rebar get-deps && rebar compile will fetch mochiweb (and any dependencies it declares), build the dependencies, and build your own code.

Using JRuby to directly call Android Java Methods

I've been recently exploring how to access Android's Libraries via JRuby in SL4A. I know it is possible to design apps with Ruboto, but I just want to right a simple script to access APIs that current SL4A doesn't offer. I can import normal jars and such but I haven't been able to get Android's API. In specific I want to access 'android.nfc'. Is there a way do accomplish this that I haven't figured out yet or is it possible to not work; SL4A does state that JRuby offers a direct API bridge though.
Thanks,
Clement
Can you include your Jruby code? Are you building your classpath properly and then doing the java_import as well?
I have a ruby file just for loading up my jars into my classpath that I require in every .rb file called java_jars.rb it contains the following:
Dir["target/dependency/\*.jar"].each { |jar| require jar }
then in the main ruby file do this:
include Java
require 'java_jars'
java_import 'com.package.name.blah.ApiClassName'
def methodName
apiObject = com.package.name.blah.ApiClassName.new
# don't forget methodName becomes method_name in JRuby
apiObject.method_name
end

Categories

Resources