Python 的 JPype 模块调用 Jar 包
背景与需求
- 最近学习并安装使用了HttpRunner框架去尝试做接口测试,并有后续在公司推广的打算。
- HttpRunner由Python开发,调用接口时需要依赖Python;而大多数公司的扩展工具包使用Java编写,测试同学使用Python重新实现不显示。
- 目前网上的资料均停留在对单个JAR包的引用于使用上,对于使用多个有依赖关系的JAR包的方法并未提及。
JPype介绍
1. JPype是什么:
JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python 在某些领域(如服务器端编程)中的不足。
JPype的实际运行环境仍然是python runtime,只是在运行期间启动了一个嵌入的jvm。
2. 环境搭建
我的开发环境是: Windows7_64bit + Python3.5_64bit + JDK1.8_64bit + +Jpype_0.5.52 (Python和JDK的位数一定要相同)
- 安装JPype: pip3.5 install JPype1-py3
- 找到JRE中的 jvm.dll文件 (在JDK中的路径类似如下路径: F:/Java/jdk1.8.0_45/jre/bin/server/jvm.dll)
3. JPype使用说明
1. 启动JVM
JPype 提供的 startJVM() 函数的作用是启动 JAVA 虚拟机,所以在后续的任何 JAVA 代码被调用前,必须先调用此方法启动 JAVA 虚拟机。
jpype.startJVM() 的定义:startJVM(jvm, *args)
3. 引用第三方JAVA扩展包
很多时候,在 python 项目中需要调用第三方的 Java 扩展包,这也是 JPype 的一个重要用途。
通过在 JVM 启动参数增加:-Djava.class.path = ext_classpath,实现在 Python 代码中调用已有的 Java 扩展包。
通过在 JVM 启动参数增加: -Djava.ext.dirs = ext_dirs , 实现在Python 代码中引入 Java 扩展包的其他依赖包。
注意事项
当有其他依赖JAR包时,一定要使用-Djava.ext.dirs = ext_dirs进行引入,否则在调用类对象时会报错:
jpype._jexception.ExceptionPyRaisable: java.lang.Exception: Class not found
2. 关闭JVM
当使用完 JVM 后,可以通过 jpype.shutdownJVM() 来关闭 JVM,该函数没有输入参数。当 python 程序退出时,JVM 会自动关闭。
4. 实践
1. 直接调用JAVA API
from jpype import *
import os.path
startJVM("F:/Java/jdk1.8.0_45/jre/bin/server/jvm.dll", "-ea")
java.lang.System.out.println("hello World")
shutdownJVM()
2. 调用JAVA第三方扩展包
JAR包源代码为:
package com.test;
import org.apache.log4j.Logger;
public class MathDemo {
public static Logger logger = Logger.getLogger(MathDemo.class.getName());
public int add(int a, int b) {
return a+b;
}
}
将此源码打包编译为:MathDemo.jar,而MathDemo.jar又依赖log4j-1.2.16.jar。
Python脚本代码为:
from jpype import *
import jpype
jarpath = os.path.join(os.path.abspath('.'), 'F:/JPypeTestl/MathDemo.jar')
dependency = os.path.join(os.path.abspath('.'), 'F:/JPypeTestl/dependency')
jpype.startJVM("F:/Java/jdk1.8.0_45/jre/bin/server/jvm.dll", "-ea", "-Djava.class.path=%s" %jarpath,"-Djava.ext.dirs=%s" %dependency) #当有依赖的JAR包存在时,一定要使用-Djava.ext.dirs参数进行引入
JClass = jpype.JClass('com.test.MathDemo')
instance = JClass()
result = (instance.add(10, 20)
print (result)
jpype.shutdownJVM()
5. 注意事项
在启动JVM的时候,默认不会把JDK中 “jrelibext” 扩展包下的JAR包引入,所以为了避免调用过程中出现问题,建议将 “jrelibext” 内的JAR, 均放入我们自己的 "dependency" 目录,自行导入。
我在工作中就遇到过使用JAVA调用JAR成功,但是使用JPypy调用JAR,缺乏ext扩展目录中JAR包的情况。
2019-10-14-云之幻-UWP-视频教程
2018-2-13-win10-uwp-自定义控件-SplitViewItem
2018-2-13-win10-uwp-自定义控件-SplitViewItem
2019-9-19-dotnet-找不到-PostAsJsonAsync-方法
2019-9-19-dotnet-找不到-PostAsJsonAsync-方法
2018-5-28-WPF-Process.Start-出现-Win32Exception-异常
2018-5-28-WPF-Process.Start-出现-Win32Exception-异常
Java实现 LeetCode 606 根据二叉树创建字符串(遍历树)
Java实现 LeetCode 606 根据二叉树创建字符串(遍历树)
- 最新文章
-
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
使用Dropbox搭建静态网站详细教程
前端性能优化(JavaScript篇)
对于移动设备页面尺寸的理解
js 中的submit 回调函数
【转自百度fex】fex-team/interview-questions
Html标签笔记
MongoDB---性能优化---(1)
二叉树总结—建树和4种遍历方式(递归&&非递归)
[LeetCode] Evaluate Reverse Polish Notation [2]
- 热门文章
-
POJ 1150 The Last Non-zero Digit 数论+容斥
ACM之跳骚---ShinePans
继承?静态代理?写一个自己的动态代理吧
Spring MVC JSON自己定义类型转换
Ajax系列之二:核心对象XMLHttpRquest
SCAN listener and Node listener – How does it work
Node.js的helloworld 程序
CF1166E The LCMs Must be Large
2018-12-27-WPF-从-DrawingVisual-转-BitmapImage-图片
2018-12-27-WPF-从-DrawingVisual-转-BitmapImage-图片