首页 > 解决方案 > 为什么 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 错误?

标签: javapythonsql-serverjythonwindows-server-2016

解决方案


您必须在运行时使用系统类加载器加载 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


推荐阅读