環境准備:
部署環境准備: 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 。
下面是一個簡單的 python 程序,通過 JPype 調用 Java 的打印函數,打印出字符串。
#/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
import jpype
jvmPath = jpype.getDefaultJVMPath()
jvmArg = "-Xint"
jpype.startJVM(jvmPath,jvmArg)
如果喲空格,就識別不出參數
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 后,可以通過 jpype.shutdownJVM() 來關閉 JVM,該函數沒有輸入參數。當 python 程序退出時,JVM 會自動關閉。
很多時候,在 python 項目中需要調用第三方的 Java 擴展包,這也是 JPype 的一個重要用途。為了使編程者方便地在 python 代碼中調用已有的 Java 擴展包,我們可以再在 JVM 啟動參數增加:
-Djava.class.path=ext_classpath
以下為調用第三方 Java 擴展包示例,(假設第三方 Java 擴展包的所在路徑是 E:\JavaExt)
import jpype jvmPath = jpype.getDefaultJVMPath() ext_classpath = “ E:\\JavaExt ” jvmArg = “ -Djava.class.path = ” + ext_classpath if not jpype.isJVMStarted(): jpype.startJVM(jvmPath, jvmArg) |
有時,某些 Java 應用需要設置或者獲取 JVM 中的系統屬性。
- 在 JVM 啟動時設置系統變量示例:
- 在 JVM 的啟動參數中加入如下參數:
-Dproperty=value
假設你要設置的屬性名為 yourProperty,屬性值為 yourValue 。
import jpype jvmPath = jpype.getDefaultJVMPath() jvmArg = "-DyourProperty=yourValue" if not jpype.isJVMStarted(): jpype.startJVM(jvmPath,jvmArg)
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))
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 類型 |
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 |
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 類:
import jpype javaClass = jpype.JClass('src.com.ibm.javaproject.JavaClass') |
調用 Java 類的構造函數生成實例:
value = “ oldvalue ” javaInstance = javaClass(value) |
調用 Java 方法:
print javaInstance.getValue() javaInstance.setValue( “ newvalue ” ) print javaInstance.getValue() |
運行結果:
oldvalue newvalue |
異常處理是程序編寫者們必須考慮的問題,在使用 JPype 的過程中,所有的 Java exception 將被自動轉換成 jpype.JavaException 。 以下是 Jpype 處理 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() |
下面我們用一個簡單的應用實例來說明如何在 python 代碼中調用 Java 類。
假設我們已用 Java 語言編寫了一個類:PasswordCipher,該類的功能是對字符串進行加密和解密。它提供了一個對外的接口 run() 函數,定義如下 :
public class PasswordCipher { …… public static String run(String action, String para){ …… } …… } |
run 函數接收兩個參數,第一個參數代表所要進行的操作,傳入“ encrypt ”表示對第二個參數 para 做加密操作,返回加密結果。如果第一個參數為“ decrypt ”則返回對 para 的解密操作的結果。在 run 函數中有可能會有異常拋出。
我們先將 PasswordCipher.class 存放在目錄“ F:\test\cipher ”下,然后用 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 |
運行該程序后得到的結果:
original string is : congratulations encrypted string is : B0CL+niNYwJLgx/9tisAcQ== decryped string is : congratulations |
原文鏈接:http://www.pythontip.com/blog/post/4245/