我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python中使用jpype调用Jar包中的实现方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python中使用jpype调用Jar包中的实现方法

使用jpype调用Jar包中的实现方法

安装

pip install jpype1(注意要加后边这个1)

使用

基本流程如下:

  • 使用jpype开启jvm
  • 加载java类
  • 调用java方法
  • 关闭jvm

说明

我这里是在Python中使用Java的第三方抽象语法树包JavaParser(Python中的javalang实在太难用了),实现得到一个类文件中的所有的方法的功能

代码

Python代码:

import jpype
import os
import json

if __name__ == '__main__':
    # 加载jar包
    jarpath = os.path.join(os.path.abspath('.'),'D:/study/hdu-cs-learning/Paper/TD/BuildDataset/target/BuildDataset.jar')
    # 获取jvm.dll的默认文件路径
    jvmPath = jpype.getDefaultJVMPath()
    # 开启虚拟机
    jpype.startJVM(jvmPath, '-ea', '-Djava.class.path=%s' % (jarpath))
    # 加载java类(参数名是java的长类名)
    javaClass = jpype.JClass('scluis.API')
    # 调用类中的方法
    class_file_path = 'D:/study/TD/OpenSourceProject/JFreeChart/source/org/jfree/chart/fx/ChartViewer.java'
    # 这里是调用scluis.API类的静态方法getMethods,如果调用实例方法,则需要先实例化java对象,即javaInstance = javaClass(),在使用实例调用
    file_methods_str = javaClass.getMethods(class_file_path)
    # 解析返回值,这里的返回值是json数组
    methods_list = ""
    if file_methods_str != "":
        methods_list = json.loads(str(file_methods_str))
    # 关闭虚拟机
    jpype.shutdownJVM()

API.java:

package scluis;
import com.github.javaparser.ParseException;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;


public class API {
    public static void main(String[] args) {
        //main方法是为了测试Java代码即,getMethods,main方法不是必须的
        String filePath="D:/study/OpenSourceProject/SQuirrel/app/class="lazy" data-src/net/sourceforge/squirrel_sql/client/gui/HelpViewerWindow.java";
        String methods=getMethods(filePath);
        System.out.println(methods);
    }
    public static String getMethods(String filePath){
        String res="";
        try {
            Parser fileParser = new Parser();
            res= fileParser.getFileMethods(filePath);
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        }
        return res;
    }
}

Parser.java(内含Java返回值格式)

package scluis;

import com.alibaba.fastjson.JSON;
import com.github.javaparser.*;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.printer.DotPrinter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class Parser {

    private CompilationUnit m_CompilationUnit;


    public CompilationUnit getParsedFile() {
        return m_CompilationUnit;
    }

    public String getFileMethods(String filePath) throws ParseException, IOException {
        String methodJson = "";
        try {
            m_CompilationUnit = StaticJavaParser.parse(new File(filePath));
            FunctionVisitor functionVisitor = new FunctionVisitor();

            functionVisitor.visit(m_CompilationUnit, null);
            ArrayList<MethodDeclaration> nodes = functionVisitor.getMethodDeclarations();
            ArrayList<Method> methodList = new ArrayList<>();
            for (int i = 0; i < nodes.size(); i++) {

                MethodDeclaration methodDeclaration = nodes.get(i);
                //起止行
                int startLine = methodDeclaration.getRange().get().begin.line;
                int endLine = methodDeclaration.getRange().get().end.line;
                //方法代码
                String method = methodDeclaration.removeComment().toString();

                Method m = new Method(startLine, endLine, method);
                methodList.add(m);
            }
            methodJson = JSON.toJSONString(methodList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return methodJson;
    }
}

jpype调用jar包“Class xx not found“问题

环境

  • Java 1.8 (64位)
  • Python 2.7.9 (32位)
  • Jpype 0.5.4.2
  • Pycharm

代码

import jpype
from jpype import *

# 该目录下有需要调用的jar包 pak.jar
jvmArg = "-Djava.ext.dirs=D:/1_Workspace/jpype_test/"
if not jpype.isJVMStarted():
     jvmPath = jpype.getDefaultJVMPath()
     jpype.startJVM(jvmPath,"-ea", jvmArg)
     # pak.jar中包含类com.abc.EFG
     jd = JClass("com.abc.EFG")
     instance = jd()
     print(instance.getName())
     jpype.shutdownJVM()

问题

执行以上代码,报错如下。Class com.abc.EFG not found

Class com.abc.EFG not found

检查点

1.在pak.jar包中有com.abc.EFG

2.EFG依赖的jar包都在同级目录下

3.Jpype使用没有问题:调用System.out.println可以打印

jprint = java.lang.System.out.println
jprint("xxx") #输出xxx

试着从环境上找原因,也许和Java版本有关。

首先查找pak.jar包的编译jdk版本

使用以上方法获得输出是 52,即对应java 1.8,与本机Java版本相符。

但是回头一想其实在Pycharm中并没有配置过Java的版本。

那么打印一下jvmPath,获得的路径是C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll,=> 使用的是 jre1.6(32位)

此时去Java1.8目录找,发现server目录下有jvm.dll,不是在client目录。管他的,尝试直接指定存在的jvm.dll路径。

# ...
# jvmPath = jpype.getDefaultJVMPath()
jvmPath = r'D:\java\jdk1.8\jre\bin\server\jvm.dll'
jpype.startJVM(jvmPath,"-ea", jvmArg)
# ...

到这里也许有人的问题可以解决了,但我的情况是还是报错…

解决

最后装了jdk1.8 32位!!!,发现在client目录下有jvm.dll文件了

再次修改代码,执行通过。

run successfully

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python中使用jpype调用Jar包中的实现方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python中使用jpype调用Jar包中的实现方法

这篇文章主要介绍了Python中使用jpype调用Jar包中的实现方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-08

java中使用jar包乱码解决方法

java使用jar包乱码解决方法:1、修改Eclipse中文本文件的默认编码:windows->Preferences->general->Workspace->Text file encoding设置为UTF-8。修改JAVA源文件的默认编码:windows
java中使用jar包乱码解决方法
2021-06-03

java使用main方法如何实现打包成jar

java使用main方法如何实现打包成jar?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java打包成jarjar -cvf [jar包的名字] [需要打包的文件]
2023-05-31

Python实现调用jar或执行java代码的方法详解

这篇文章主要介绍了Python实现调用jar或执行java代码的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-21

PHP中调用JS方法的实现方法

PHP是一种广泛应用于网站开发的服务器端脚本语言,而JS(JavaScript)则是一种用于网页交互的客户端脚本语言。在开发网站时,我们有时需要在PHP代码中调用JS方法来实现一些特定的功能,比如在某个条件下弹出提示框或执行一段动态生成的J
PHP中调用JS方法的实现方法
2024-03-04

Java实现从jar包中读取指定文件的方法

本文实例讲述了Java实现从jar包中读取指定文件的方法。分享给大家供大家参考,具体如下:以下的Java代码实现了从一个jar包中读取指定文件的功能:/*** This class implements the funcationality
2023-05-31

Python正确调用 jar 包加密得到加密值的操作方法

前言 在做接口自动化的时候,经常会遇到一些参数是需要加密的,比如密码参数。 加密规则一般开发也不愿意告诉你,会直接给你一个jar包,让你调用jar包得到加密值,在jmeter上是可以直接引用jar包的,但python调用jar包会有点麻烦。
2022-06-02

在SQL Server中使用命令调用SSIS包的具体方法

在SQL Server中可以使用dtexec命令运行SSIS包(2005以上版本),当然也可以通过系统过程:xp_cmdshell调用dtexec运行SSIS包
2022-11-15

python中根据字符串调用函数的实现方法

在python中可以根据字符串来调用函数: 1、使用getattr从字符串来调用函数 在多进程中,可能传递过来的是一个字符串,那么我怎么来调用一个已经存在的函数呢,主要就是使用到getattr函数的作用,这个函数就是在使用字符串得到这个字符
2022-06-04

python中调用sh最方便的方法

from sh import ifconfigprint(ifconfig("wlan0"))详见http://amoffat.github.io/sh/
2023-01-31

怎么在python中使用__name__方法调用模块

怎么在python中使用__name__方法调用模块?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。python主要应用领域有哪些1、云计算,典型应用OpenStack。2、
2023-06-14

golang中strings包的Replace使用方法

这篇文章将为大家详细讲解有关golang中strings包的Replace使用方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。函数声明:func Trim(s string, cutset string
2023-06-14

Java中调用Python的实现示例

本文主要介绍了Java中调用Python的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-18

python函数嵌套调用的实现方法

这篇文章主要讲解了“python函数嵌套调用的实现方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python函数嵌套调用的实现方法”吧!说明1、在一个函数中又调用了另一个函数,调用函数t
2023-06-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录