python调用.jar文件 —— 安装openjdk,而无需配置JAVA环境

文章目录

  • 一、什么是 .jar 文件 ?
  • 1.1、.jar 文件结构
  • 1.2、.jar 清单文件(MANIFEST.MF)
  • 二、python 调用 .jar
  • 2.1、使用 Py4J 库
  • 2.1.1、Py4J 环境配置 —— OpenJDK 开源免费库
  • 2.1.2、创建 Java 程序
  • 2.1.3、编译和运行 Java 程序
  • 2.1.4、编写 Python 客户端
  • 2.2、使用 JPype 库(亲测有效)
  • 2.2.1、JPype 环境配置 —— OpenJDK 开源免费库
  • 2.2.2、启动 JVM 并调用 Java 类
  • 实战一:(JPype)python 调用 helloworld.jar
  • 实战二:(JPype)python 调用 hello-world-1.1.11.jar
  • 实战三:(JPype)python 调用 ImarisLib.jar + 获取 Imaris 版本号
  • 一、什么是 .jar 文件 ?

    .jar(Java ARchive,Java归档)文件一种用于分发 Java 类文件(.class 文件)、Java 应用程序和相关资源(如:图像、音频文件、配置文件等)的文件格式。

    .jar 文件的主要特点

  • 压缩格式:使用 ZIP 格式进行压缩,能够减少文件大小,并将多个文件打包成一个易于分发的单一文件。
  • 清单文件:每个 .jar 文件包含一个名为 MANIFEST.MF 的清单文件,位于 META-INF 目录中。提供了关于 .jar 文件的元数据信息,如:版本信息、类路径、主类(入口点)等。
  • 主类(Main-Class):指定 .jar 文件的主类,即应用程序的入口点。
  • 类路径(Class-Path):指定 .jar 文件依赖的其他 .jar 文件或目录的路径。它允许 .jar 文件引用外部库。
  • 可执行 JAR 文件:如果 .jar 文件中包含一个 Main-Class 入口在 MANIFEST.MF 中定义,.jar 文件可以被直接执行。
  • .jar 文件的主要用途

  • 分发 Java 应用程序:.jar 文件可以打包整个 Java 应用程序,包括编译后的类文件和所有必需的资源。
  • 创建 Java 库:可以将 Java 类库打包到 .jar 文件中,供其他 Java 应用程序使用。
  • 便捷的部署:.jar 文件使得分发和部署 Java 应用程序变得更加方便。
  • 简化项目管理:使用 .jar 文件可以将多个类文件和资源组织在一起,简化项目的管理和配置。
  • 1.1、.jar 文件结构

    MyApp.jar
    |
    |-- META-INF/
    |   |-- MANIFEST.MF
    |   |-- other-metadata-file  (可选的其他元数据文件,如签名文件)
    |
    |-- com/
    |   |-- example/
    |       |-- MyClass.class   (主要的类文件)
    |       |-- AnotherClass.class  (其他类文件)
    |       |
    |       |-- utils/
    |           |-- HelperClass.class  (工具类文件)
    |
    |-- resources/  (资源文件,如配置文件、图像等)
    |   |-- config.properties
    |   |-- logo.png
    |
    |-- lib/  (可能的依赖库,包含其他 JAR 文件)
    |   |-- external-library-1.jar
    |   |-- external-library-2.jar
    |
    |-- doc/  (文档目录,包含项目文档)
    |   |-- README.md
    |   |-- LICENSE.txt
    |   |-- API_Documentation.html
    
    

    1.2、.jar 清单文件(MANIFEST.MF)

    Manifest-Version: 1.0							清单文件的版本号
    Main-Class: com.example.MainClass				指定 JAR 文件的主类
    Class-Path: lib/library1.jar lib/library2.jar	指定其他 JAR 文件的路径
    
    Created-By: 1.6.0_45 (Sun Microsystems Inc.)	表示创建 JAR 文件所用的 Java 运行时环境(JRE)或 Java 开发工具包(JDK)的版本和供应商信息。
    		1.6.0_45 表示 Java 版本 6 更新 45。
    		Sun Microsystems Inc. 表示这个 JRE 或 JDK 是由 Sun Microsystems(现在是 Oracle 的一部分)开发的。
    

    二、python 调用 .jar

    在 python 中,调用 .jar 文件的方法主要有两种:

  • Py4J:适合在 Python 中通过 TCP/IP 连接到 Java 程序。你需要编写一个 Java 程序来启动 GatewayServer 并暴露接口。Python 客户端通过 JavaGateway 连接到这个服务器。
  • JPype直接在 Python 中调用 Java 类,不需要单独的 Java 程序。你可以启动 JVM,并通过 JPype 导入和使用 Java 类。
  • 只学习并打通了JPype,适用于我的需求。

    2.1、使用 Py4J 库

    Py4J 允许 Python 程序调用 Java 代码。它需要一个 Java 程序来启动一个 GatewayServer,然后 Python 客户端连接到这个服务器。

    2.1.1、Py4J 环境配置 —— OpenJDK 开源免费库

  • (1)安装 Py4J 库:pip install py4j
  • (2)配置 Java 环境
  • 方法一:在Windows系统中安装 JDK 工具 + 手动配置环境变量 JAVA_HOME
  • 安装 JDK:从 Oracle 或 OpenJDK 网站下载并安装 JDK。
  • 配置环境变量:
  • (1)此电脑 – 鼠标右击 – 属性 – 高级系统设置 – 环境变量;
  • (2)在系统变量中 – 新建 – 变量名(JAVA_HOME)变量值(C:\Program Files\Java\jdk-22)
  • (3)在系统变量中 – Path – 添加:(%JAVA_HOME%\bin;)(%JAVA_HOME%\jre\bin)
  • 方法二:无需在系统中安装 JDK + 无需手动配置环境变量 JAVA_HOME
  • 在 Python 中,安装 OpenJDK 开源免费库 :conda install openjdk=11 -y

  • 考虑到部分用户在本机上安装过 JDK,则可能出现以下两种情况:

  • (1)已安装 JDK + 环境变量配置成功,则正常运行;
  • (2)已安装 JDK + 环境变量配置异常,则删除环境变量JAVA_HOME,并重启 IDE(如 PyCharm)以避免错误。
  • 否则可能提示:未检测到 jvm.dll —— No JVM shared library file (jvm.dll) found. Try setting up the JAVA_HOME environment variable properly.
  • 方法一(适用范围):完整的 Java 开发环境、安装和配置较繁琐
  • 方法二(适用范围):仅需要运行 Java 程序(例如与 JPype 集成)而不需要开发、自动化安装、仅限于虚拟环境中使用。

  • 2.1.2、创建 Java 程序

    编写一个 Java 程序,启动 GatewayServer 并暴露 Java 对象。

    //ImarisServer.java
    import py4j.GatewayServer;
    
    public class ImarisServer {
        private ImarisClass imaris;
    
        public ImarisServer() {
            this.imaris = new ImarisClass();  // 初始化你的 Java 类
        }
    
        public void callSomeMethod() {
            imaris.someMethod();  // 调用 Java 类中的方法
        }
    
        public static void main(String[] args) {
            ImarisServer app = new ImarisServer();
            GatewayServer server = new GatewayServer(app);
            server.start();
            System.out.println("Gateway Server Started");
        }
    }
    
    

    2.1.3、编译和运行 Java 程序

    javac -cp path/to/py4j.jar ImarisServer.java
    java -cp .:path/to/py4j.jar:path/to/Imaris.jar ImarisServer
    

    参数:
    path/to/py4j.jar:是 Py4J 的 JAR 文件
    path/to/Imaris.jar:是包含你的 Java 类的 JAR 文件。

    2.1.4、编写 Python 客户端

    from py4j.java_gateway import JavaGateway
    
    gateway = JavaGateway()  # 连接到 Java Gateway(默认连接到 localhost:25333)
    imaris_server = gateway.entry_point  # 获取 Java 对象
    imaris_server.callSomeMethod()  # 调用 Java 方法
    

    2.2、使用 JPype 库(亲测有效)

    在 python 中,使用 JPype 启动一个 JVM(Java Virtual Machine),并允许 Python 直接调用 Java 类和方法。

    2.2.1、JPype 环境配置 —— OpenJDK 开源免费库

    确保 Java 与 JPype 版本兼容 —— JPype 支持 Java 6 到 Java 17 版本。

  • (1)安装 JPype 库:pip install jpype1
  • (2)配置 Java 环境
  • 方法一:在Windows系统中安装 JDK 工具 + 手动配置环境变量 JAVA_HOME
  • 安装 JDK:从 Oracle 或 OpenJDK 网站下载并安装 JDK。
  • 配置环境变量:
  • (1)此电脑 – 鼠标右击 – 属性 – 高级系统设置 – 环境变量;
  • (2)在系统变量中 – 新建 – 变量名(JAVA_HOME)变量值(C:\Program Files\Java\jdk-22)
  • (3)在系统变量中 – Path – 添加:(%JAVA_HOME%\bin;)(%JAVA_HOME%\jre\bin)
  • 方法二:无需在系统中安装 JDK + 无需手动配置环境变量 JAVA_HOME
  • 在 Python 中,安装 OpenJDK 开源免费库 :conda install openjdk=11 -y

  • 考虑到部分用户在本机上安装过 JDK,则可能出现以下两种情况:

  • (1)已安装 JDK + 环境变量配置成功,则正常运行;
  • (2)已安装 JDK + 环境变量配置异常,则删除环境变量JAVA_HOME,并重启 IDE(如 PyCharm)以避免错误。
  • 否则可能提示:未检测到 jvm.dll —— No JVM shared library file (jvm.dll) found. Try setting up the JAVA_HOME environment variable properly.
  • 方法一(适用范围):完整的 Java 开发环境、安装和配置较繁琐
  • 方法二(适用范围):仅需要运行 Java 程序(例如与 JPype 集成)而不需要开发、自动化安装、仅限于虚拟环境中使用。

  • 2.2.2、启动 JVM 并调用 Java 类

    实战一:(JPype)python 调用 helloworld.jar

    【helloworld.jar】下载地址:https://github.com/jarirajari/helloworld

    HelloWorld.class:打印信息

    Python 命令,用于测试和验证 JPype(Java-Python Bridge)与 JVM(Java 虚拟机)是否正确安装和配置:python -c "import jpype; print(jpype.getDefaultJVMPath()); jpype.startJVM(jpype.getDefaultJVMPath()); print(jpype.isJVMStarted()); jpype.shutdownJVM()"

    import jpype
    import jpype.imports
    
    # (1)检查JVM是否已经启动,如果没有启动,则启动JVM。在同一个 Python 进程中,只能启动一次 JVM
    if not jpype.isJVMStarted():
        # 使用jpype1启动JVM,并指定JAR文件的类路径 ———— classpath参数是一个包含JAR文件路径的列表
        jpype.startJVM(classpath=[r"F:\py\helloworld.jar"])
        
    # (2)使用JClass获取指定的Java类 ————  jar文件路径:io\github\javaf\HelloWorld.class
    HelloWorld = jpype.JClass('HelloWorld')
    print("Methods in HelloWorld class:", dir(HelloWorld))
    
    # (3)调用 Java 类的方法
    HelloWorld.main([])
    
    # (4)# 关闭 JVM
    jpype.shutdownJVM()
    
    """Hello world from HelloWorld.jar!"""
    
    实战二:(JPype)python 调用 hello-world-1.1.11.jar

    【hello-world-1.1.11.jar】下载地址:https://mavenlibs.com/jar/file/io.github.javaf/hello-world

    HelloWorld.class:创建一个简单的命令行程序,提示用户输入一个问题的答案。

    import jpype
    import jpype.imports
    
    if not jpype.isJVMStarted():
        """#############################################################################################
        # 函数功能:检查 Java 虚拟机(JVM)是否已经启动。
        # 函数说明:jpype.isJVMStarted()
        # 参数说明:
        #         无参数。
        # 返回值:
        #         布尔值:如果 JVM 已经启动,则返回 True;否则返回 False。
        #############################################################################################"""
    
        jpype.startJVM(classpath=[r"F:\py\hello-world-1.1.11.jar"])
        """#############################################################################################
        # 函数功能:启动 Java 虚拟机(JVM),使 Python 程序可以调用 Java 类和方法。
        # 函数说明:jpype.startJVM(jvm, *args, **kwargs)
        # 参数说明:
        #         jvm:字符串,表示要使用的 JVM 的路径。通常为 Java 安装目录中的 'jvm.dll' 或 'libjvm.so'。
        #         *args:可选参数,传递给 JVM 的其他参数,如类路径(-Djava.class.path=路径)或 JVM 选项(如 -Xmx512m)。
        #         **kwargs:可选参数,额外的关键字参数,包括:
        #             classpath:字符串或列表,指定 Java 类的类路径。
        #             ignoreUnrecognized:布尔值,默认为 False。如果为 True,则忽略 JVM 不识别的参数。
        # 返回值:
        #         无返回值。
        # 注意事项:
        #         - 只能启动一次 JVM,在同一个 Python 进程中不能再次启动。
        #         - JVM 一旦启动,就无法停止或重新启动。
        #############################################################################################"""
    
    # (1)使用JPackage访问指定的Java包下的所有类类 ————  jar文件夹路径:io\github\javaf
    package = jpype.JPackage('io.github.javaf')
    print("Classes in package:", dir(package))
    """#############################################################################################
    # 类功能:用于从 Java 包中动态加载类,可以用于访问 Java 包下的所有类。
    # 类说明:jpype.JPackage(package_name)
    # 参数说明:
    #         package_name:字符串,表示 Java 包的名称。
    # 返回值:
    #         返回一个 JPackage 对象,可以用于访问指定包下的类。
    
    #############################################################################################"""
    
    # (2)使用JClass获取指定的Java类 ————  jar文件路径:io\github\javaf\HelloWorld.class
    HelloWorld = jpype.JClass('io.github.javaf.HelloWorld')
    print("Methods in HelloWorld class:", dir(HelloWorld))
    """#############################################################################################
    # 类功能:从 Java 类的完全限定名创建一个 Python 类,用于调用 Java 类的静态方法、静态字段以及创建实例。
    # 类说明:jpype.JClass(name, loader=None)
    # 参数说明:
    #         name:字符串,表示 Java 类的完全限定名(包括包名)。
    #         loader:可选参数,表示类加载器,可以是 Java 类加载器实例或类加载器名称。默认为 None,表示使用默认类加载器。
    # 返回值:
    #         返回一个 Python 类,可以用于调用对应的 Java 类中的方法、字段以及实例化对象。
    # 使用示例:
    #         MyClass = jpype.JClass('com.example.MyClass')
    #         my_instance = MyClass()  # 创建 Java 类的实例
    #         MyClass.staticMethod()   # 调用 Java 类的静态方法
    #         print(MyClass.staticField)  # 访问 Java 类的静态字段
    #############################################################################################"""
    # (3)调用 Java 类的方法
    HelloWorld.main([])
    
    jpype.shutdownJVM()
    """#############################################################################################
    # 函数功能:关闭已经启动的 Java 虚拟机(JVM)。
    # 函数说明:jpype.shutdownJVM()
    # 参数说明:
    #         无参数。
    # 返回值:
    #         无返回值。
    # 注意事项:
    #         - 关闭 JVM 后,不能再次启动。同一进程中只能启动和关闭一次 JVM。
    #         - 在关闭 JVM 前,确保所有的 Java 资源已经被释放,以防止资源泄漏。
    #         - 如果 JVM 尚未启动,调用此函数不会有任何效果。
    #############################################################################################"""
    
    
    实战三:(JPype)python 调用 ImarisLib.jar + 获取 Imaris 版本号

    【ImarisLib.jar】下载地址:https://github.com/bleach1by1/BIRDS_plugin

    BPImarisLib.class:定义了一个名为 BPImarisLib 的类,主要用于与 Imaris 服务器进行交互。

    import jpype
    import jpype.imports
    from jpype.types import *
    
    
    def get_object_id(v_imaris_lib):
        try:
            v_server = v_imaris_lib.GetServer()
            v_number_of_objects = v_server.GetNumberOfObjects()
            for v_index in range(v_number_of_objects):
                v_object_id = v_server.GetObjectID(v_index)
                return v_object_id  # 返回第一个对象 ID
        except Exception as e:
            print(f"Error: {str(e)}")
            print("Please reload image to Imaris")
        return -1  # 无效的 ID
    
    
    if __name__ == '__main__':
        jpype.startJVM(classpath=[r"F:\py\pyinstaller\BIRDSpyd\BIRDS\code\cache\ImarisLib.jar"])  # 启动 JVM 并指定 JAR 文件路径
        # from com.bitplane.xt import BPImarisLib  # 导入 Java 包
        BPImarisLib = jpype.JClass('com.bitplane.xt.BPImarisLib')  # jar压缩包文件路径:com\bitplane\xt\BPImarisLib.class
        print("Methods in HelloWorld class:", dir(BPImarisLib))
    
        # 若没有Imaris软件或不需要获取Imaris版本号,则直接调用 ImarisLib.jar 即可。
        if False:
            v_imaris_lib = BPImarisLib()  # 创建 Java 对象
            imaris_id = get_object_id(v_imaris_lib)  # 调用获取对象 ID 的函数
            print(f"Imaris_ID={imaris_id}")  # Imaris_ID=1(测试版本号:Imaris9.0.1)
    
        jpype.shutdownJVM()  # 关闭 JVM
    
    """##################################################################
    # (0)classpath路径不存在或不正确
    	TypeError: Class com.bitplane.xt.BPImarisLib is not found
    	
    # (1)若Imaris软件没有打开
        Error: 'NoneType' object has no attribute 'GetNumberOfObjects'
        Please reload image to Imaris
        Imaris_ID=-1
    
    # (2)若Imaris软件已经打开
        Imaris_ID=0
    ##################################################################"""
    
  • ImarisLib.jar:是 Imaris 软件的 Java API 库,通常包含在 Imaris 安装包中。
  • Imaris:Imaris 是一个(商业)图像分析和处理软件,由 Bitplane 开发。由于 Imaris 是商业软件,你需要从 官方渠道 购买以获得软件的使用权。

  • 作者:胖墩会武术

    物联沃分享整理
    物联沃-IOTWORD物联网 » python调用.jar文件 —— 安装openjdk,而无需配置JAVA环境

    发表回复