zoukankan      html  css  js  c++  java
  • (转载)Python 的 JPype 模块调用 Jar 包

    Python 的 JPype 模块调用 Jar 包

    背景与需求

    1. 最近学习并安装使用了HttpRunner框架去尝试做接口测试,并有后续在公司推广的打算。
    2. HttpRunner由Python开发,调用接口时需要依赖Python;而大多数公司的扩展工具包使用Java编写,测试同学使用Python重新实现不显示。
    3. 目前网上的资料均停留在对单个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的位数一定要相同)

    1. 安装JPype: pip3.5 install JPype1-py3
    2. 找到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包的情况。

  • 相关阅读:
    Java中遍历Set集合的方法
    分布式RPC框架Apache Dubbo
    CSS:页面美化和布局控制
    JavaScript实例
    Codeforces Round #604 题解
    洛谷P1533 可怜的狗狗题解
    Educational Codeforces Round 81 题解
    P1494 [国家集训队]小Z的袜子 题解
    洛谷P1283 平板涂色题解
    洛谷P1220 关路灯题解
  • 原文地址:https://www.cnblogs.com/jasmine-Jobs/p/10014643.html
Copyright © 2011-2022 走看看