Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to import Java classes from Jython module

Note: I found the solution and answered myself. Though, I have no idea why that setting was wrong and caused the problem. I'm still interested in having a good explanation about how Jython import system works; if anyone cares to gain the bounty please answer that.


I'm working on an existing Java EE project where I need to do computations in Python. I'm at the first stages of integration tests but I'm already facing an issue. I read Chapter 10 of Jython book but still can't find a solution. I also read Chapter 8 (Modules and Packages for Code Reuse) but to me it'is unclear.

An explanation of how Jython import system works and how to configure it would be very appreciated.

The problem:

$ jython -v
import: 'exceptions' as org.python.core.exceptions in builtin modules
Jython 2.5.3 (2.5:c56500f08d34+, Aug 13 2012, 14:54:35) 
[Java HotSpot(TM) Server VM (Oracle Corporation)] on java1.7.0_10
import: import site # precompiled from /home/me/jython/2.5.3/Lib/site$py.class
import: 'sys' as sys in builtin modules
import: import os # precompiled from /home/me/jython/2.5.3/Lib/os$py.class
import: 'errno' as org.python.modules.errno in builtin modules
import: 'posix' as org.python.modules.posix.PosixModule in builtin modules
import: import posixpath # precompiled from /home/me/jython/2.5.3/Lib/posixpath$py.class
import: import stat # precompiled from /home/me/jython/2.5.3/Lib/stat$py.class
import: 'java' as java package
import: 'File' as java class
import: 'IOException' as java class
import: 'org' as java package
import: 'Py' as java class
Type "help", "copyright", "credits" or "license" for more information.

>>> import pendulum.generator.BuildingType
import: import pendulum # precompiled from /path/to/project/build/classes/pendulum/__init__$py.class
import: import pendulum.generator # precompiled from /path/to/project/build/classes/pendulum/generator/__init__$py.class
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named BuildingType

My question is: what am I doing wrong and how do I fix things to import BuildingType interface successfully? Maybe the problem stands in CLASSPATH, but I have no idea which value could be appropriate.


Code organization:

$ tree build/classes/pendulum/generator/ src/pendulum/generator/
build/classes/pendulum/generator/
├── BuildingType.class
├── __init__.py
└── __init__$py.class

src/pendulum/generator/
├── BuildingType.java
└── __init__.py

Import path defined by a private Jython registry file:

$ cat ~/.jython 
python.path=\
/path/to/project/build/classes:\
/path/to/project/src:\
/home/me/jdevel/extras/2.5.3/Lib:\
/home/me/jdevel/extras/2.5.3/Lib/site-packages

I'm sure Jython picks up the paths because I checked that with sys.path at Jython prompt.

BuildingType.java

package pendulum.generator;

public interface BuildingType {
    public String getBuildingName();
    public String getBuildingAddress();
    public String getBuildingId();
}
like image 855
Paolo Avatar asked Feb 14 '13 16:02

Paolo


People also ask

How do I import libraries into Jython?

Methods in this class can be called from the Jython script importex.py. Save and execute the above script from the command line to get following output. C:\jython27\bin>jython importex.py Hello World!

Does Jython require Python installation?

Yes. Jython is an implementation of the Python language in Java.

What version of Python does Jython use?

It was released on 21 March 2020 and is compatible with Python 2.7.


2 Answers

You need to set CLASSPATH as well as python.path.

With the same directory layout, this works for me:

jython10$ CLASSPATH=build/classes/  jython -v Building.py
import: 'exceptions' as org.python.core.exceptions in builtin modules
import: import site # precompiled from /usr/local/Java/jython2.5.3/Lib/site$py.class
import: 'sys' as sys in builtin modules
import: import os # precompiled from /usr/local/Java/jython2.5.3/Lib/os$py.class
import: 'errno' as org.python.modules.errno in builtin modules
import: 'posix' as org.python.modules.posix.PosixModule in builtin modules
import: import posixpath # precompiled from /usr/local/Java/jython2.5.3/Lib/posixpath$py.class
import: import stat # precompiled from /usr/local/Java/jython2.5.3/Lib/stat$py.class
import: java package as '/Users/sdm7g/jaxp/jython10/build/classes/pendulum'
import: 'pendulum' as java package
import: 'pendulum' as java package
import: java package as '/Users/sdm7g/jaxp/jython10/build/classes/pendulum/generator'
import: 'pendulum.generator' as java package
import: 'BuildingType' as java class

Reference: Working with CLASSPATH (Jython Book).

like image 198
Steven D. Majewski Avatar answered Nov 15 '22 15:11

Steven D. Majewski


After a lot of time wasted in try/catch approach I was able to find the answer myself.

.jython have to look like this:

python.path=\
/path/to/project/build:\
/path/to/project/src:\
/home/me/jdevel/extras/2.5.3/Lib:\
/home/me/jdevel/extras/2.5.3/Lib/site-packages

Not this:

python.path=\
/path/to/project/build/classes:\
/path/to/project/src:\
/home/me/jdevel/extras/2.5.3/Lib:\
/home/me/jdevel/extras/2.5.3/Lib/site-packages

In particular, adding /path/to/project/build/classes to the import path is wrong (even if it reflects the filesystem hierarchy), while /path/to/project/build is right and solved the issue.

like image 25
Paolo Avatar answered Nov 15 '22 16:11

Paolo