龙空技术网

为什么Python通过Jar包的方式不能同时链接多个异构库?

hxliu666 75

前言:

眼前姐妹们对“无法访问jarfile的错误”大概比较关切,我们都需要学习一些“无法访问jarfile的错误”的相关文章。那么小编同时在网上汇集了一些有关“无法访问jarfile的错误””的相关内容,希望各位老铁们能喜欢,看官们快快来学习一下吧!

问题复现

在上一篇文章Python连接数据库的三种方式中,遗留了一个问题,就是通过jar包的方式连接数据库时,如果我们使用的是多数据源的话,我们应该怎么处理呢?现在我把整个过程梳理一下(>>> jaydebeapi.__version__;'1.2.3'):

通过前文,大家清楚了通过jar包是如何连接数据库的,其实和通过JDBC进行连接的配置是一样。大致所需内容如下:

jaydebeapi.connect(jclassname=driver, url=url, driver_args=[user, password], jars=jarFile)//简单来讲,和Java里面配置数据库所需要的连接信息一致。
那么如果是连接连接两个数据源且不同种类的库呢?正常来讲,我们会通过如下的方式来写(source_conn 和 des_conn……):
source_conn = jaydebeapi.connect(jclassname=source_driver, url=source_url, driver_args=[source_user, source_password], jars=source_jarFile)des_conn = jaydebeapi.connect(jclassname=des_driver, url=des_url, driver_args=[des_user, des_password], jars=des_jarFile)
错误原因分析:

在写完之后,本以为可以正常运行达到自己预期的时候,结果报错了?报错信息如下:

jpype._jclass.NoClassDefFoundError: java.lang.NoClassDefFoundError: oracle/jdbc/driver/OracleDriver//这里面报错信息很直接明了。NoClass

从上面的错误代码中,我们很清楚地看到,明明参数都配置了,传参也指定了,为什么呢?通过报错信息,我简单地阅读了一下源码。我的理解如下:

完整的报错信息

从完整的报错信息,我们可以看到关联到的几个文件。先看“__init__.py”文件,部分代码如下:

报错信息412行相关信息

从上图中,可以清楚地看到。这部分主要在处理参数,最后去调用函数“_jdbc_connect”,接下来我们继续去看报错信息中提示的报错行数221,相关内容如下:

报错信息221相关内容

从上图中,可以看到,报错的地方是在“jpype.JClass(jclassname)”,那么它为什么会报错呢?请大家看我划的左侧红线,说明报错的地方和蓝色的框是同一层级的。蓝色的地方要执行的前期是“if not jpype.isJVMStarted():”,而我们在执行第一个“source_conn”时,相关的参数信息已经传入并且已经连接成功了,说明它已经不符合jvm不启动的分支,所以不会进入相关的流程,只有进入相关的流程才会处理jars等相关参数。所以 在执第二个“des_conn”时,“jpype.JClass(jclassname)”,参数jars还是原来的值,jclassname和jars对应关系不存在而发生的错误,简单来讲就是找不到对应的jar包而导致的报错

如果大家仔细看的话,在分析错误信息的时候,其实有个小小的漏洞,就是我们在412行看到“_jdbc_connect“,为什么到了212行时,发现函数尽然是”_jdbc_connect_jpype“,为什么呢?原因如下:

解决方法:

通过上面的分析,我们初步可以确定出现问题的原因,那么我们该如何解决此问题呢?从上面可以看到它只加载一次,那么我们让它一次加载所有jar包进去就可以了。解决方法如下:

一次性写到文件中格式如下:

jarfile=['./ojdbc6-11.2.0.3.jar','./mysql-connector-java-8.0.22.jar']
从配置文件中获取

配置文件格式如下:

jarFile = ./ojdbc6-11.2.0.3.jar,./mysql-connector-java-8.0.22.jar

Python文件中可以通过模块configparser来获取并进行转化

jarFile = config_raw.get("GLOBAL","jarFile")jarFile = jarFile.split(",") 

下面是验证一些想法的操作,供大家参考。

我修改了源文件,添加了相应的输出,以此来验证自己的想法是否正确。

下面分别是正确和报错的两次输出结果如下:

正确输出

错误输出

通过上面的对比,可以看到它就加载了一次jar包。上面是我对此问题的一些理解。谢谢!

标签: #无法访问jarfile的错误