python 调用 java代码有多种方式,暂且说一下使用jpype类库进行python对java代码的使用
一. 环境配置
S1:先查看当前电脑python的版本,我的是python 64位
S2: 安装 Jpype1 类库
我本地pip install jpype1 的时候报错,所以本次通过下载 jpype1的离线安装包进行安装
jpype1下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype,
下载成功之后pip进行安装:pip install JPype11.0.2cp37cp37mwin32-amd64.whl
备注:1.选择与自己python相匹配的进行下载
(比如:我的python是37就选择cp37,命名中带有amd64是适应python64位的,没有amd64的是适应python32位的,所以下载:JPype11.0.2cp37cp37mwin32-amd64.whl )
2.如果安装失败,请先安装wheel,才能安装whl离心安装包:pip install wheel
S3: java的jre虚拟环境
python运行java代码,需要启用java的jre虚拟环境,这个jre虚拟环境依赖于 jvm.dll。所以我们需要拿到jvm.dll的路径用于后续的python代码。
第一种情况:如果本地安装了jdk,并且版本也是64位,也设置了java_home 的环境变量,这一步可以直接跳过。
第二种情况:下载 jre,找到相关的jvm.dll 路径。
jre下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html
备注:安装jre 要与python版本位数保持一致
S4: 准备java的 jar包:编写java项目,发版生成 jar包。比如:pythonCall.jar
二. 代码实现
def demo(): ''' python 调用 java代码的demo ''' # 获取环境变量的jvm.dll 路径, # 从下载的jre中获取jvm.dll:jvmPath = C:\a_Python\AAA\calljavaproject\jre\XX\jvm.dll jvmPath = jpype.getDefaultJVMPath() # 启动java的jvm虚拟环境 jpype.startJVM(jvmPath) # 模拟java的代码,打印 字符串 jpype.java.lang.System.out.println("hello world!") # 关闭java虚拟环境 jpype.shutdownJVM()
因为我代码多出的case用到java的加密,所以多次调用的时候报错:JVM is already started 或者 JVM cannot be restarted,所以修改代码如下:
def start_jvm(self, sysname=""): try:
# 如果 jvm环境已经启动,则直接返回成功;如没有启动,则进入else,开启java的虚拟环境 if jpype.isJVMStarted(): return True else: # 启动java的jvm # S1: 加载 java的jar包(java程序的打包) jarpath = os.path.join(JAVA_JAR_PATH, "pythonCall.jar") # S2: 开启 jvm 虚拟环境 jpype.startJVM(self.jvmpath, "-Djava.class.path=" + jarpath) return True
except Exception as e: log.error(sysname + "系统启动java的jvm虚拟环境出现错误,错误原因:" + str(e)) return False
具体代码如下:
import os
import jpype
from common.util.logHelper import log
class CallJava():
def __init__(self):
# 获取 jvm.dll 路径:使用环境变量
self.jvmpath = jpype.getDefaultJVMPath()
def start_jvm(self, sysname=""):
try:
# 如果已经启动jvm的虚拟环境则跳过;否则进入else,启动java的虚拟环境
if jpype.isJVMStarted():
return True
else:
# 启动java的jvm
# S1: 加载 java的jar包(java程序的打包)
jarpath = os.path.join(JAVA_JAR_PATH, "pythonCall.jar")
# S2: 开启 jvm 虚拟环境
jpype.startJVM(self.jvmpath, "-Djava.class.path=" + jarpath)
return True
except Exception as e:
log.error(sysname + "系统启动java的jvm虚拟环境出现错误,错误原因:" + str(e))
return False
def java_encrypt(self, sysname, body, keys):
"""
加密方法: des(key).encrypt("system=sysname(系统名),time=body(当前时间)")
注意:调用java方法,由于我写的是静态方法,直接使用类名就可以调用方法;
如果不是静态,需要先初始化类,在调用类方法。
sysname: "系统名"
body:"待加密内容"
keys:"密钥"
"""
response = ""
try:
if self.start_jvm(sysname):
# S3: 加载 java 内相关的类文件(参数是java内的长类名)
javaclass = jpype.JClass("com.pythoncalljava.JavaClass")
# 加密方法:javaClass.encrypt("系统名", "明文", "密钥")
response = str(javaclass.encrypt(sysname, body, keys))
except Exception as e:
log.error(sysname + "系统调用java加密方法出错,错误原因:" + str(e))
return response
def java_encrypt_accesssecret(self, sysname, body, accesssecret, key):
"""
加密方法: 加密后的内容 = des(key).encrypt(system=sysname,time=body,accessSecret=accessSecret)
sysname: "系统名"
body:"待加密内容"
keys:"密钥"
accesssecret: "访问密码"
"""
response = ""
try:
if self.start_jvm(sysname):
javaclass = jpype.JClass("com.pythoncalljava.SignJavaClass")
response = str(javaclass.encrypt(sysname, body, accesssecret, key))
except Exception as e:
log.error(sysname + "系统调用java加密方法出错,错误原因:" + str(e))
return response
def java_decrypt(self, sysname, keys, encrypt_body):
"""
解密: des(秘钥).decrypt(encrypt_body(加密的报文))
keys:"密钥"
encrypt_body:"加密内容"
"""
response = ""
try:
if self.start_jvm(sysname):
javaclass = jpype.JClass("com.pythoncalljava.JavaClass")
# 解密方法:javaClass.decrypt("密钥","加密内容")
response = javaclass.decrypt(keys, encrypt_body)
except Exception as e:
log.error(sysname + "系统调用java解密方法出错,错误原因:" + str(e))
return response
def java_decrypt_accesssecret(self, sysname, keys, encrypt_body):
"""
解密: des(秘钥).decrypt(encrypt_body(加密的报文))
keys:"密钥"
encrypt_body:"加密内容"
"""
response = ""
try:
if self.start_jvm(sysname):
javaclass = jpype.JClass("com.pythoncalljava.SignJavaClass")
# 解密方法:javaClass.decrypt("密钥","加密内容")
response = javaclass.decrypt(keys, encrypt_body)
except Exception as e:
log.error(sysname + "系统调用java解密方法出错,错误原因:" + str(e))
return response
def shutdown_java_jvm(self):
"""
关闭java虚拟环境
"""
try:
if self.start_jvm():
jpype.shutdownJVM()
except Exception as e:
log.error("关闭java的jvm虚拟环境出错,错误原因:" + str(e))
return False
|