java - 为什么 CLASSPATH 对 Python 失败但对 RazorSQL 有效?
问题描述
在 Windows Server 2016 上,我们尝试使用 Jython 脚本通过 JDBC 进行连接,但它给出了以下错误:
java.lang.ClassNotFoundException: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
同一台机器上的 RazorSQL 使用以下设置无错误地连接:
Driver Class: com.microsoft.sqlserver.jdbc.SQLServerDriver
Driver Location: \Program Files (x86)\RazorSQL\drivers\sqlserver\sqljdbc.jar
因此,我们使用以下命令将 CLASSPATH 设置为相同的位置:
set CLASSPATH=C:\Program Files (x86)\RazorSQL\drivers\sqlserver\sqljdbc.jar
...但是在运行下面的代码时 - 我们仍然得到相同的 ClassNotFound 错误。
这是我们的 Python 代码:
jclassname = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
database = "our_database_name"
db_elem = ";databaseName={}".format(database) if database else ""
host = "###.##.###.###" # ip address
port = "1433"
user = "user_name"
password = "password"
url = (
jdbc:sqlserver://{host}:{port}{db_elem}"
";user={user};password={password}".format(
host=host, port=port, db_elem=db_elem,
er=user, password=password)
)
print url
driver_args = [url]
jars = None
libs = None
db = jaydebeapi.connect(jclassname, driver_args, jars=jars,
libs=libs)
这就是我们运行 Python 脚本的方式:
C:\jython2.7.0\bin\jython.exe C:\path_to_our_script.py
RazorSQL 是如何连接良好的——但不知何故 Python 不能?我们如何删除这个 CLASSPATH 错误?
解决方案
您必须在运行时使用系统类加载器加载 JAR。
请参考这个答案。
以下代码片段取自此Gist。
def loadJar(jarFile): '''load a jar at runtime using the system Classloader (needed for JDBC) adapted from http://forum.java.sun.com/thread.jspa?threadID=300557 Author: Steve (SG) Langer Jan 2007 translated the above Java to Jython Reference: https://wiki.python.org/jython/JythonMonthly/Articles/January2007/3 Author: seansummers@gmail.com simplified and updated for jython-2.5.3b3+ >>> loadJar('jtds-1.3.1.jar') >>> from java import lang, sql >>> lang.Class.forName('net.sourceforge.jtds.jdbc.Driver') <type 'net.sourceforge.jtds.jdbc.Driver'> >>> sql.DriverManager.getDriver('jdbc:jtds://server') jTDS 1.3.1 ''' from java import io, net, lang u = io.File(jarFile).toURL() if type(jarFile) <> net.URL else jarFile m = net.URLClassLoader.getDeclaredMethod('addURL', [net.URL]) m.accessible = 1 m.invoke(lang.ClassLoader.getSystemClassLoader(), [u]) if __name__ == '__main__': import doctest doctest.testmod()
另请查看 - https://wiki.python.org/jython/JythonMonthly/Articles/January2007/3
推荐阅读
- typescript - 用 Typescript 编写的 NPM 包 - 定义面向公众的 API
- assembly - x86 程序集:即使实现正确,交换函数的输出也不正确
- c - 在 WARN_ON_ONCE 宏定义中使用 !!、__warned 和 __ret_warn_once 作为 int
- wpf - WPF:为什么 PreviewMouseLeftButtonDown EventTrigger 有效而 MouseLeftButtonDown 无效?
- reactjs - 如何在 React 中将 postgres 时间格式(没有时区的时间戳)转换为 Date 对象(Sun Dec 01 2019 17:55:25 GMT+0530(India Standard Time)?
- html - XQUERY 在找到的条件元素之后选择一个元素
- javascript - 如何使用控件控制 3D CSS 立方体
- python - 将背景颜色添加到作为子布局的布局(在另一个布局内)
- typescript - 在 Typescript 中使用装饰器模式时如何使参数的类型保持一致
- javascript - 无法验证 google cloud vision api。如何对其进行认证以进一步使用它