jpype-python調用java的方法


 

 

環境准備:

部署環境准備:
 sed -i.ori '$a export JAVA_HOME=/opt/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
source /etc/profile

java -version
yum install -y python3
mv /etc/yum.repos.d/mcwbak/* /etc/yum.repos.d/
yum install -y python3
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 
python3 get-pip.py
pip install jpype
tar xf jpype-0.0.tar.gz 
python setup.py install
pip install jpype1

 

簡介: Python 作為一種靈活的軟件開發語言在當今被廣泛使用。在軟件開發過程中,有時需要在 Python 項目中利用既有的 Java 代碼,已達到節省時間和開發成本的目的。因此,找到一個 Python 代碼調用 Java 代碼的橋梁是非常有意義的。 JPype 就是這樣的一個工具,利用它可以使 Python 程序方便的調用 Java 代碼,從而擴充 Python 語言的能力,彌補 Python 語言的不足。 本文介紹了如何利用 JPype 整合 Python 程序和 Java 程序的一些基本方法。

概覽

JPype 是一個能夠讓 python 代碼方便地調用 Java 代碼的工具,從而克服了 python 在某些領域(如服務器端編程)中的不足。

下載

JPype 可以從 sourceforge 網站上下載:http://sourceforge.net/projects/jpype/ 目前 JPype 最新的版本為 0.5.4,支持 python 2.5 和 2.6. 本文以 Windows XP 平台,python 2.5.4 為例闡述。

安裝

安裝 JPype 前需要先安裝 python 。從 http://www.python.org/download 下載 python 並安裝,安裝路徑選擇 C:\Python25\,安裝完成后在本地 C 盤應有 C:\Python25 目錄,該目錄下有 python.exe 文件。 Python 安裝完后,雙擊下載的 JPype 安裝文件即可安裝 JPype 。

許可證

JPype 遵循的許可證是 Apache License V2.0 。

 

JPype 的使用

一個簡單的 hello world 程序

下面是一個簡單的 python 程序,通過 JPype 調用 Java 的打印函數,打印出字符串。


清單 1. hello world

#/usr/bin/env python3
import jpype 
jvmPath = jpype.getDefaultJVMPath() 
jpype.startJVM(jvmPath) 
jpype.java.lang.System.out.println( " hello world! " ) 
jpype.shutdownJVM()

啟動 JVM

JPype 提供的 startJVM() 函數的作用是啟動 JAVA 虛擬機,所以在后續的任何 JAVA 代碼被調用前,必須先調用此方法啟動 JAVA 虛擬機。

  • jpype.startJVM() 的定義
    startJVM(jvm, *args)
  • jpype.startJVM() 的參數

    參數 1: jvm, 描述你系統中 jvm.dll 文件所在的路徑,如“ C:\Program Files\IBM\Java50\jre\bin\j9vm\jvm.dll ”。可以通過調用 jpype.getDefaultJVMPath() 得到默認的 JVM 路徑。

    參數 2: args, 為可選參數,會被 JPype 直接傳遞給 JVM 作為 Java 虛擬機的啟動參數。此處適合所有合法的 JVM 啟動參數,例如:

     

     -agentlib:libname[=options] 
     -classpath classpath 
     -verbose 
     -Xint

     


清單 2. jpype.startJVM() 的用法示例

import jpype
jvmPath = jpype.getDefaultJVMPath()
jvmArg = "-Xint"
jpype.startJVM(jvmPath,jvmArg)

 

 

 如果喲空格,就識別不出參數 

 

 

判斷 JVM 是否啟動

JPype 提供的 jpype.isJVMStarted() 函數的作用是判斷 JVM 是否已啟動。

  • jpype.isJVMStarted() 的定義 
    isJVMStarted()
  • jpype.isJVMStarted() 的返回值
    返回值為 True 表示 JVM 已經啟動,返回值為 False 表示 JVM 還未啟動


清單 3. jpype.isJVMStarted() 的用法示例

import jpype 
jvmPath = jpype.getDefaultJVMPath() 
jvmArg = "-Xint"
if not jpype.isJVMStarted(): 
   jpype.startJVM(jvmPath,jvmArg)

  

 

 

關閉 JVM

當使用完 JVM 后,可以通過 jpype.shutdownJVM() 來關閉 JVM,該函數沒有輸入參數。當 python 程序退出時,JVM 會自動關閉。

引用第三方的 Java 擴展包

很多時候,在 python 項目中需要調用第三方的 Java 擴展包,這也是 JPype 的一個重要用途。為了使編程者方便地在 python 代碼中調用已有的 Java 擴展包,我們可以再在 JVM 啟動參數增加:

-Djava.class.path=ext_classpath

以下為調用第三方 Java 擴展包示例,(假設第三方 Java 擴展包的所在路徑是 E:\JavaExt)


清單 4. 調用第三方 Java 擴展包示例

import jpype 
 jvmPath = jpype.getDefaultJVMPath() 
 ext_classpath = “ E:\\JavaExt ”
 jvmArg = “ -Djava.class.path = ” + ext_classpath 
 if not jpype.isJVMStarted(): 
    jpype.startJVM(jvmPath, jvmArg)

 

訪問 Java 的系統屬性

有時,某些 Java 應用需要設置或者獲取 JVM 中的系統屬性。

  • 在 JVM 啟動時設置系統變量示例:
  • 在 JVM 的啟動參數中加入如下參數:
    -Dproperty=value 
    假設你要設置的屬性名為 yourProperty,屬性值為 yourValue 。


清單 5. JVM 啟動時設置系統變量示例

import jpype 
jvmPath = jpype.getDefaultJVMPath() 
jvmArg = "-DyourProperty=yourValue"
if not jpype.isJVMStarted(): 
   jpype.startJVM(jvmPath,jvmArg)


清單 6. 在程序中設置系統變量示例

import jpype 
prop = "yourProperty"
value = "yourValue"
system = jpype.JClass('java.lang.System') 
system.setProperty(str(prop),str(value))

 

添加上啟動jvm

import jpype 
prop = "yourProperty"
value = "yourValue"
jvmPath = jpype.getDefaultJVMPath() 
jpype.startJVM(jvmPath)
system = jpype.JClass('java.lang.System') 
system.setProperty(str(prop),str(value))

 

 

清單 7. 在程序中獲取系統變量示例

import jpype 
prop = "yourProperty"
system = jpype.JClass('java.lang.System') 
value = system.getProperty(str(prop))
print(value)

 

啟動jvm,設置環境變量。獲取並打印環境變量

import jpype 
prop = "yourProperty"
value = "yourValue"
jvmPath = jpype.getDefaultJVMPath() 
jpype.startJVM(jvmPath)
system = jpype.JClass('java.lang.System') 
system.setProperty(str(prop),str(value))
value = system.getProperty(str(prop))
print(value)

 

import jpype 
 prop = “ yourProperty ”
 system = jpype.JClass('java.lang.System') 
 value = system.getProperty(str(prop))

 

Java 類型到 python 類型的轉換


表 1. Java 類型到 python 類型的轉換

Java 類型 轉換成的 python 類型
byte, short and int int
long long
float and double float
boolean int of value 1 or 0
char unicode of length 1
String unicode
arrays JArray
other Java object JavaObject
Class JavaClass
array Class JavaArrayClass

 

使用 Java 對象


清單 8. Java 類定義

package src.com.ibm.javaproject; 

 public class JavaClass { 
    public String value = ""; 

    /** 
     * Creates a new JavaClass object. 
     * 
     * @param value 
     */ 
 public JavaClass(String value) { 
        this.value = value; 
    } 

    public String getValue() { 
        return this.value; 
    } 

    public void setValue(String val) { 
        this.value = val; 
    } 
 } 

 

對於上述的 Java 類,以下的代碼介紹了如何在 Python 中構造並且使用相應的對象。 首先是獲得對應 Java 類:


清單 9. 獲得對應 Java 類

import jpype 
 javaClass = jpype.JClass('src.com.ibm.javaproject.JavaClass') 

 

調用 Java 類的構造函數生成實例:


清單 10. 調用 Java 類的構造函數生成實例

value = “ oldvalue ”
 javaInstance = javaClass(value) 

 

調用 Java 方法:


清單 11. 調用 Java 方法

print javaInstance.getValue() 
 javaInstance.setValue( “ newvalue ” ) 
 print javaInstance.getValue() 

 

運行結果:


清單 12. Python 代碼的運行結果

oldvalue 
 newvalue

 

Java exception 錯誤處理

異常處理是程序編寫者們必須考慮的問題,在使用 JPype 的過程中,所有的 Java exception 將被自動轉換成 jpype.JavaException 。 以下是 Jpype 處理 Java exception 的示例:


清單 13. 處理 Java exception

from jpype import JavaException 
 try: 
    #Code that throws a java.lang.RuntimeException 
 except JavaException, ex: 
    if JavaException.javaClass() is java.lang.RuntimeException: 
        print "Caught the runtime exception : ", JavaException.message() 
        print JavaException.stackTrace()

 

 

應用實例(Password Cipher)

下面我們用一個簡單的應用實例來說明如何在 python 代碼中調用 Java 類。

Java 類定義

假設我們已用 Java 語言編寫了一個類:PasswordCipher,該類的功能是對字符串進行加密和解密。它提供了一個對外的接口 run() 函數,定義如下 :


清單 14. PasswordCipher 定義

public class PasswordCipher { 
    ……
    public static String run(String action, String para){ 
    ……
    } 
……
 } 

 

run 函數接收兩個參數,第一個參數代表所要進行的操作,傳入“ encrypt ”表示對第二個參數 para 做加密操作,返回加密結果。如果第一個參數為“ decrypt ”則返回對 para 的解密操作的結果。在 run 函數中有可能會有異常拋出。

Python 代碼

我們先將 PasswordCipher.class 存放在目錄“ F:\test\cipher ”下,然后用 python 語言編寫下面的代碼:


清單 15. Python 代碼

import jpype 
 from jpype import JavaException 

 jvmPath = jpype.getDefaultJVMPath()           #the path of jvm.dll 
 classpath = "F:\\test\\cipher"                 #the path of PasswordCipher.class 
 jvmArg = "-Djava.class.path=" + classpath 
 if not jpype.isJVMStarted():                    #test whether the JVM is started 
    jpype.startJVM(jvmPath,jvmArg)             #start JVM 
 javaClass = jpype.JClass("PasswordCipher")   #create the Java class 
 try: 
    testString = "congratulations" 
    print "original string is : ", testString 
    #call the run function of Java class 
    encryptedString = javaClass.run("encrypt", testString) 
    print "encrypted string is : ", encryptedString 

    #call the run function of Java class 

    decryptedString = javaClass.run("decrypt", encryptedString) 
    print "decryped string is : ", decryptedString 
 except JavaException, ex: 
    print "Caught exception : ", JavaException.message() 
    print JavaException.stackTrace() 
 except: 
    print "Unknown Error" 
 finally: 
    jpype.shutdownJVM()        #shut down JVM 

 

運行該程序后得到的結果:


清單 16. 該程序運行的結果是:

original string is :  congratulations 
 encrypted string is :  B0CL+niNYwJLgx/9tisAcQ== 
 decryped string is :  congratulations

 

原文鏈接:http://www.pythontip.com/blog/post/4245/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM