前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[1250]python调用java代码的工具jpype

[1250]python调用java代码的工具jpype

作者头像
周小董
发布2023-12-25 09:29:11
3840
发布2023-12-25 09:29:11
举报
文章被收录于专栏:python前行者
文章目录
  • jpype简介
  • 安装
  • 使用
    • 小试牛刀
    • 使用命令行方式打jar包
    • 调用jar包方法
      • 问题1:shutdownJVM停止后restart失败的情况
      • 问题2:只能调用静态方法
      • 问题3:调用其他包方法
    • 调用jar包main方法
      • java命令行方式运行jar包

jpype简介

JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python 在某些领域(如服务器端编程)中的不足。

Jython 是给 Java程序员 运行 Python 程序用的。JPype是给python程序员玩的

github:https://github.com/jpype-project/jpype

安装

注意点:python和java的位数一定要一致

代码语言:javascript
复制
C:\Users\admin>java -version
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)

C:\Users\admin>python
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
  • 安装 jpype
代码语言:javascript
复制
pip install jpype1

第二种:下载whl包安装 下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/

使用

小试牛刀
代码语言:javascript
复制
import os
import jpype


# 使用自定义jvm
# jvmPath = r'D:\soft\java\jdk\jre\bin\server\jvm.dll'
# 使用java环境默认jvm
jvmPath = jpype.getDefaultJVMPath()
print('jvmPath:',jvmPath)

jpype.startJVM(jvmPath)
jpype.java.lang.System.out.println("hello world!")
jpype.shutdownJVM()

输出结果:

代码语言:javascript
复制
hello world!

注意点:JAVA_HOME一定要配置对,要不然找不到

jpype.getDefaultJVMPath() #这里说明了其实我们不用装JDK只要安装和python位数一致的JRE就行了 这个也是可以配置的:默认的是使用的JDK中自带的jre,我们可以只安装jre的情况下指定这个路径

使用命令行方式打jar包

在Java中,可以使用以下命令将代码打包为jar包:

使用命令行方式: 使用javac命令编译源代码文件为class文件:javac MyClass.java 使用jar命令创建jar包:jar cf myJar.jar MyClass.class 这将编译MyClass.java文件并将生成的class文件打包到名为myJar.jar的jar包中。

调用jar包方法
代码语言:javascript
复制
import os
import jpype
 
 
def java_class_func(jar_path, class_name, func_name, jvm_path=None, *args):
    """
    调用jar包中class下的方法
    :return:
    """
    # jar包路径的配置
    # jarpath = os.path.join(os.path.abspath("."), "D:\\hf-0.1.jar")
    jarpath = os.path.join(os.path.abspath(".."), jar_path)
    # 这里指定了jvm
    if jvm_path:
        jvmpath = jvm_path
    else:
        jvmpath = jpype.getDefaultJVMPath()
    jpype.startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % jarpath)
 
    # 这里是指定哪个class,执行哪个方法,入参和结果展示
    # java_class = jpype.JClass("com.dubbo.testjsf.R2mUtils")
    # java_class.getCustKeys()
    
    java_class = jpype.JClass(class_name)
    ru_param = ','.join(list(map(lambda x: json.dumps(x), args)))
 
    ########################################################################
    # 判断是否有中文在里面,有就转成unicode,后来发现是pycharm的编码格式问题,这里就注释了
    # def _iszh(p):
    #     for c in p:
    #         if '\u4e00' <= c <= '\u9fa5':
    #             return True
    #     return False
    #
    # args_list = list(map(lambda x: json.dumps(x) if _iszh(x) else x, args))
    ########################################################################
 
    res = eval("java_class.%s(%s)" % (func_name, ru_param))
    print(res)  # 打印有返回值方法的结果
    jpype.shutdownJVM()
 
 
if __name__ == '__main__':
    java_class_func(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                    "com.dubbo.testjpype.Jpype",
                    "func1",
                    "C:\\Java\\jre\\bin\\client\\jvm.dll")
    java_class_func(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                    "com.dubbo.testjpype.Jpype",
                    "func4",
                    "C:\\Java\\jre\\bin\\client\\jvm.dll",
                    "第一个参数",
                    "第二个参数")
 
    java_class_func(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                    "com.dubbo.testjpype.Jpype",
                    "func2",
                    None,
                    "第一个参数")
 
    java_class_func(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                    "com.dubbo.testjpype.Jpype",
                    "func3",
                    None,
                    "1",
                    3)
问题1:shutdownJVM停止后restart失败的情况

解决:可以遍历需要调用的类、方法、入参,做个结构体设计,就可以调用多个方法的情况

代码语言:javascript
复制
# -*- coding:utf-8 -*-
import json
import os
 
import jpype
 
def java_class_func1(jar_path, actions, jvm_path=None):
    """
    调用jar包中class下的方法
    :return:
    """
    jarpath = os.path.join(os.path.abspath(".."), jar_path)
    # 这里指定了jvm
    if jvm_path:
        jvmpath = jvm_path
    else:
        jvmpath = jpype.getDefaultJVMPath()
    jpype.startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % jarpath)
 
    for class_name, func_name, in_params in actions:
        java_class = jpype.JClass(class_name)
        ru_param = ','.join(list(map(lambda x: json.dumps(x), in_params)))
        res = eval("java_class.%s(%s)" % (func_name, ru_param))
        print(res)  # 打印有返回值方法的结果
    jpype.shutdownJVM()
 
 
if __name__ == '__main__':
    java_class_func1(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                     [
                         ["com.dubbo.testjpype.Jpype", "func1", []],
                         ["com.dubbo.testjpype.Jpype", "func2", ["第一个参数"]]
                     ]
                     )
问题2:只能调用静态方法

解决:用静态方法调用类方法

问题3:调用其他包方法
代码语言:javascript
复制
if __name__ == '__main__':
    java_class_func1(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                     [
                         ["com.dubbo.testjsf.JpypeThree", "func1", []],
                         ["com.dubbo.testjpype.JpypeOther", "func1", []],
                         ["com.dubbo.testjpype.Jpype", "func1", []],
                         ["com.dubbo.testjpype.Jpype", "func2", ["第一个参数"]],
                         ["com.dubbo.testjpype.Jpype", "func3", ["1", 3]],
                         ["com.dubbo.testjpype.Jpype", "func4", ["第一个参数", "第二个参数"]],
                         ["com.dubbo.testjpype.Jpype", "func5", []],
                         ["com.dubbo.testjpype.Jpype", "func0", []]
                     ]
                     )
调用jar包main方法
代码语言:javascript
复制
# -*- coding:utf-8 -*-
import json
import os
 
import jpype
 
def java_class_main(jar_path, class_name, main_args, jvm_path=None):
    """
    调用jar包中class下的main方法
    :return:
    """
    jarpath = os.path.join(os.path.abspath(".."), jar_path)
    if jvm_path:
        jvmpath = jvm_path
    else:
        jvmpath = jpype.getDefaultJVMPath()
    jpype.startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % jarpath)
    # 使用JClass调用main方法
    # jpype.JClass(class_name).main(main_args)
    # 使用JPackage调用main方法
    # jpype.JPackage("com").dubbo.testlala.Jpype.main(main_agrs)
    v1, v2 = class_name.split(".", 1)
    eval('jpype.JPackage("%s").%s.main(%s)' % (v1, v2, main_args))
    jpype.shutdownJVM()
 
if __name__ == '__main__':
        java_class_main(r"D:\mycode\javacode\jsf_hf_demo\hf\target\hf-0.2.jar",
                    "com.dubbo.testjpype.Jpype",
                    '["第一个参数","第二个参数","第三个参数"]')
java命令行方式运行jar包
代码语言:javascript
复制
# 指定jar中调用那个class的main函数(java -cp jar的路径 class路径)
java -cp .\hf\target\hf-0.1.jar com.dubbo.testjsf.Get22

#jar中调用MANIFEST.MF配置的入口class的main函数
java -jar .\hf\target\hf-0.1.jar

#main方法有入参的情况(java -cp jar包路径 class路径  main的入参多个就空格分开)
java -cp .\hf\target\hf-0.1.jar com.dubbo.testjsf.Get22 "15910843034" "143121321"
java -cp .\hf\target\hf-0.1.jar com.dubbo.testjsf.Get22 asktest dsf

参考:https://blog.csdn.net/chenchen_nini/article/details/123878699 https://www.python100.com/html/4ZZ134CWW17K.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • jpype简介
  • 安装
  • 使用
    • 小试牛刀
      • 使用命令行方式打jar包
        • 调用jar包方法
          • 问题1:shutdownJVM停止后restart失败的情况
          • 问题2:只能调用静态方法
          • 问题3:调用其他包方法
        • 调用jar包main方法
          • java命令行方式运行jar包
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档