How to call a java function from python/numpy?

后端 未结 3 425
陌清茗
陌清茗 2020-12-30 12:26

it is clear to me how to extend Python with C++, but what if I want to write a function in Java to be used with numpy?

Here is a simple scenario: I want to compute

3条回答
  •  自闭症患者
    2020-12-30 12:51

    I spent some time on my own question and would like to share my answer as I feel there is not much information on this topic on stackoverflow. I also think Java will become more relevant in scientific computing (e.g. see WEKA package for data mining) because of the improvement of performance and other good software development features of Java.


    In general, it turns out that using the right tools it is much easier to extend Python with Java than with C/C++!


    Overview and assessment of tools to call Java from Python

    • http://pypi.python.org/pypi/JCC: because of no proper documentation this tool is useless.

    • Py4J: requires to start the Java process before using python. As remarked by others this is a possible point of failure. Moreover, not many examples of use are documented.

    • JPype: although development seems to be death, it works well and there are many examples on it on the web (e.g. see http://kogs-www.informatik.uni-hamburg.de/~meine/weka-python/ for using data mining libraries written in Java) . Therefore I decided to focus on this tool.

    Installing JPype on Fedora 16

    I am using Fedora 16, since there are some issues when installing JPype on Linux, I describe my approach. Download JPype, then modify setup.py script by providing the JDK path, in line 48:

    self.javaHome = '/usr/java/default'
    

    then run:

    sudo python setup.py install
    

    Afters successful installation, check this file:

    /usr/lib64/python2.7/site-packages/jpype/_linux.py

    and remove or rename the method getDefaultJVMPath() into getDefaultJVMPath_old(), then add the following method:

    def getDefaultJVMPath():
        return "/usr/java/default/jre/lib/amd64/server/libjvm.so"
    

    Alternative approach: do not make any change in the above file _linux.py, but never use the method getDefaultJVMPath() (or methods which call this method). At the place of using getDefaultJVMPath() provide directly the path to the JVM. Note that there are several paths, for example in my system I also have the following paths, referring to different versions of the JVM (it is not clear to me whether the client or server JVM is better suited):

    • /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/x86_64/client/libjvm.so
    • /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/x86_64/server/libjvm.so
    • /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/amd64/server/libjvm.so

    Finally, add the following line to ~/.bashrc (or run it each time before opening a python interpreter):

    export JAVA_HOME='/usr/java/default'
    

    (The above directory is in reality just a symbolic link to my last version of JDK, which is located at /usr/java/jdk1.7.0_04).

    Note that all the tests in the directory where JPype has been downloaded, i.e. JPype-0.5.4.2/test/testsuite.py will fail (so do not care about them).

    To see if it works, test this script in python:

    import jpype 
    jvmPath = jpype.getDefaultJVMPath() 
    jpype.startJVM(jvmPath)
    # print a random text using a Java class
    jpype.java.lang.System.out.println ('Berlusconi likes women') 
    jpype.shutdownJVM() 
    

    Calling Java classes from Java also using Numpy

    Let's start implementing a Java class containing some functions which I want to apply to numpy arrays. Since there is no concept of state, I use static functions so that I do not need to create any Java object (creating Java objects would not change anything).

    /**
     * Cookbook to pass numpy arrays to Java via Jpype
     * @author Mannaggia
     */
    
    package test.java;
    
    public class Average2 {
    
    public static double compute_average(double[] the_array){
        // compute the average
        double result=0;
        int i;
        for (i=0;i
                                                            
提交回复
热议问题