Python使用jpype的踩坑記錄
一:需求
近期接到一個(gè)需求, 對(duì)方部門給了java的jar包和demo。 要求我們與他們進(jìn)行HTTP通信需要使用他們的Java寫的加解密算法進(jìn)行加密和簽名。 我們的服務(wù)全部都是PY寫的, 因此如果使用PY對(duì)對(duì)方提供的jar包進(jìn)行重寫, 風(fēng)險(xiǎn)大, 而且開發(fā)周期長(zhǎng)。 為了快速的解決這樣的問題, 我們采用另外的解決方案----- 使用jpype用py直接調(diào)用java的jar包。
二:jpype介紹
用途:python調(diào)用java包的工具
安裝:pip install JPype1
官方文檔:https://jpype.readthedocs.io/en/latest/userguide.html
依賴環(huán)境:服務(wù)器上必須具備Java環(huán)境, 如果是容器化部署, 需要先安裝Java。
三:jpype的使用
封裝jarloader.py 來啟動(dòng)jvm和加載java的類。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2023/4/4 11:36 # @Author : shanwen.ren@xiaoying.com # @Notice : java包加載工具 import jpype from threading import RLock class JarLoader: __rlock = RLock() __started = False @classmethod def start_jvm(cls, classpath, *args): if cls.__started: return with cls.__rlock: if not cls.__started: # 加載JVM, 在系統(tǒng)中自動(dòng)查找 jvmPath = jpype.getDefaultJVMPath() base_args = [jvmPath, "-ea", "-Dfile.encoding=utf-8"] base_args += list(args) if args else [] # 啟動(dòng)JVM jpype.startJVM(*base_args, convertStrings=False, classpath=classpath) cls.__started = True @staticmethod def load_class(client_path): # 加載jar包中的類, 返回類, 注意返回的不是對(duì)象。 Klass = jpype.JClass(client_path) return Klass @classmethod def close(cls): jpype.shutdownJVM() cls.__started = False
使用注意事項(xiàng)
class_paths 是所有的jar包列表
例如:
dir_path = os.path.dirname(__file__) client_sdk_path = os.path.join(dir_path, "java_jars/pd-client-sdk-1.2.jar") bcprov_path = os.path.join(dir_path, "java_jars/bcprov-jdk15on-1.67.jar") bcpkix_path = os.path.join(dir_path, "java_jars/bcpkix-jdk15on-1.67.jar") gson_path = os.path.join(dir_path, "java_jars/gson-2.10.1.jar") jsch_path = os.path.join(dir_path, "jsch-0.1.55.jar") class_paths = [client_sdk_path, bcprov_path, bcpkix_path, gson_path, jsch_path]
client_path 是jar包中的實(shí)現(xiàn)類路徑
例如:client_path = “cn.aaa.sdk.service.impl.XXXX類”
四:類型轉(zhuǎn)換問題
由官方文檔可只, 某些類型是可以自動(dòng)轉(zhuǎn)換的, 而有些是不能轉(zhuǎn)換的。
例如:java類需要傳遞一個(gè)Long類型, 但是Py3中沒有Long類型了, 如果直接調(diào)用, 拋出類型不一致的問題。
解決方案: python的Int類型先轉(zhuǎn)換成Jlon類型, 然后直接塞到Java的類中。
例如: jpype.JLong(file_size)
五:容器部署問題
容器化部署的時(shí)候, 需要依賴Java環(huán)境。
解決方案: Dockerfile文件中增加一下指令。
先下載jdk包: 我用的是:jdk-8u181-linux-x64.tar.gz
FROM python:3.8.8 AS builder # 安裝JVM,配置JAVA環(huán)境變量 ADD jdk-8u181-linux-x64.tar.gz /usr/local/jdk ENV JAVA_HOME=/usr/local/jdk/jdk1.8.0_181 PATH=$JAVA_HOME/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.ja
六:JDK版本問題
問題描述:在測(cè)試環(huán)境是否jpype沒有任何的異常, 但是在生產(chǎn)環(huán)境部署后, 發(fā)現(xiàn)jpype調(diào)用java的時(shí)候, 路徑中的密鑰讀取不進(jìn)去。
案例:錯(cuò)誤提示: Caused by: java.lang.RuntimeException: java.security.InvalidKeyException: Illegal key size or default parameters at com.
分析原因:
低版本的JDK, 由于美國的出口限制,Sun通過權(quán)限文件(local_policy.jar、US_export_policy.jar)做了相應(yīng)限制。密鑰長(zhǎng)度最大128。 因此如果密鑰超過128位, 就會(huì)拋出這個(gè)異常。
解決方案:
方案一:升級(jí)服務(wù)器的JDK版本,我從1.8.0_72,升級(jí)到1.8.0_181, 解決了該問題。
方案二:下載Oracle官方網(wǎng)站上的無政策限制權(quán)限文件, 替換掉自己版本中的這兩個(gè)文件(local_policy.jar、US_export_policy.jar)
無限制文件鏈接:https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下載后將%JAVA_HOME%\jre\lib\security中的local_policy.jar 和US_export_policy.jar替換為下載包中的的local_policy.jar 和US_export_policy.jar。
到此這篇關(guān)于Python使用jpype的踩坑記錄的文章就介紹到這了,更多相關(guān)Python jpype內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Python實(shí)現(xiàn)Excel轉(zhuǎn)Markdown表格
Markdown(也簡(jiǎn)稱md)作為一種輕量級(jí)標(biāo)記語言,因其易寫易讀,效果美觀大方,不僅被眾多網(wǎng)站使用,也是程序員們做筆記、寫文檔的首選。本文將利用Python實(shí)現(xiàn)Excel轉(zhuǎn)Markdown表格,感興趣的可以了解一下2022-04-04Python編程實(shí)現(xiàn)從字典中提取子集的方法分析
這篇文章主要介紹了Python編程實(shí)現(xiàn)從字典中提取子集的方法,結(jié)合實(shí)例形式對(duì)比分析了Python采用字典推導(dǎo)式與序列轉(zhuǎn)換實(shí)現(xiàn)字典提取子集的相關(guān)操作技巧與優(yōu)缺點(diǎn),需要的朋友可以參考下2018-02-02python輕松辦公將100個(gè)Excel中符合條件的數(shù)據(jù)匯總到1個(gè)Excel里
這篇文章主要為大家介紹了python輕松辦公將100個(gè)Excel中符合條件的數(shù)據(jù)匯總到1個(gè)Excel里示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Python使用tkinter模塊實(shí)現(xiàn)GUI界面的學(xué)生信息管理系統(tǒng)流程分步詳解
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)易學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2023-01-01python如何通過注冊(cè)表動(dòng)態(tài)管理組件
使用注冊(cè)表的主要優(yōu)勢(shì)是可以在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建對(duì)象,從而實(shí)現(xiàn)高度可配置和可擴(kuò)展的設(shè)計(jì),這篇文章主要介紹了python如何通過注冊(cè)表動(dòng)態(tài)管理組件,需要的朋友可以參考下2024-05-05詳解Golang 與python中的字符串反轉(zhuǎn)
這篇文章主要介紹了詳解Golang 與python中的字符串反轉(zhuǎn)的相關(guān)資料,這里提供了實(shí)現(xiàn)的實(shí)例以便大家學(xué)習(xí)理解,需要的朋友可以參考下2017-07-07