Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Informix JDBC驱动程序处理不相关的连接字符串?_Jdbc_Informix - Fatal编程技术网

为什么Informix JDBC驱动程序处理不相关的连接字符串?

为什么Informix JDBC驱动程序处理不相关的连接字符串?,jdbc,informix,Jdbc,Informix,当Informix JDBC驱动程序出现在我的类路径中时,它似乎会在适当的驱动程序获得机会之前拦截并拒绝所有连接字符串 例如,像jdbc:ghmghmghm这样完全无意义的连接字符串将导致以下堆栈跟踪: java.sql.SQLException: Invalid sub-protocol Invalid sub-protocol: 'ghmghmghm' at com.informix.util.IfxErrMsg.getLocSQLException(IfxErrMsg.java:4

当Informix JDBC驱动程序出现在我的类路径中时,它似乎会在适当的驱动程序获得机会之前拦截并拒绝所有连接字符串

例如,像
jdbc:ghmghmghm
这样完全无意义的连接字符串将导致以下堆栈跟踪:

java.sql.SQLException: Invalid sub-protocol Invalid sub-protocol: 'ghmghmghm'
    at com.informix.util.IfxErrMsg.getLocSQLException(IfxErrMsg.java:493)
    at com.informix.jdbc.IfxDriver.checkURL(IfxDriver.java:560)
    at com.informix.jdbc.IfxDriver.connect(IfxDriver.java:208)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
我的理解是,表现良好的JDBC驱动程序将自己限制为以其神奇前缀开头的连接字符串。Informix驱动程序坏了,还是我有不合理的期望

更新

如果我只删除Informix驱动程序,而保留所有其他驱动程序,则异常会转到更正常的状态

java.sql.SQLException: No suitable driver found for jdbc:ghmghmghm
    at java.sql.DriverManager.getConnection(DriverManager.java:596)
    at java.sql.DriverManager.getConnection(DriverManager.java:187)
此外,如果删除Informix驱动程序,则有特定的有效连接字符串jdbc:sybase:Tds:leeta:5001/leeta_ase1,但如果存在Informix,则会失败(Informix无效子协议堆栈跟踪)

我的结论是Informix并没有正确地拒绝完全不匹配的连接字符串,并且Informix在Sybase连接字符串上获得了第一次破解(但不是我尝试过的所有其他连接字符串类型…)

我的Linux JDK是

java version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)
但我也看到过错误的连接字符串导致Windows上的官方Java8上出现Infx跟踪。我从未见过在Windows上截获Sybase,但这可能是一个类路径排序问题

更新2

我无法反驳我的说法,即Informix截获并拒绝了完全有效的连接字符串。我一定是在尝试非常糟糕的字符串,看到Informix堆栈,删除Informix驱动程序作为响应,然后认为来自正确驱动程序的堆栈是一个胜利(因为它允许快速修复连接字符串)

我看到了一些改进方法:

  • 只要驱动程序类已知,就停止使用
    DriverManager
    (直接实例化驱动程序,并对其调用
    getConnection()
  • DriverManager.getConnection()
    编写一个替换项,至少通过
    Throwable.addsupprested()报告所有拒绝堆栈
  • Monkey使用Java类路径试图使Informix(和其他不好的参与者)稍后出现在驱动程序列表中(per)
  • 使用
    DriverManager.(de)registerDriver()
    将坏角色(静态列表或运行时动态测试)移动到驱动程序列表的末尾

感谢所有的反馈

根据
驾驶员管理器
文档:

作为初始化的一部分,DriverManager类将尝试加载“jdbc.drivers”系统属性中引用的驱动程序类。这允许用户自定义其应用程序使用的JDBC驱动程序。例如,在~/.hotjava/properties文件中,可以指定:

jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver

假设您有3个JDBC驱动程序,您的
JDBC.Drivers
属性如下所示:

jdbc.drivers=com.DriverA:com.DriverB:com.DriverC
如果调用
DriverManager.getConnection(“jdbc:driverA:blahblah”)
DriverManager不知道使用
jdbc.drivers
属性中的哪个驱动程序,因此它必须迭代所有驱动程序

DriverManager.getConnection()可能会执行类似的操作:

公共连接getConnection(字符串url){
Set drivers=//jdbc.drivers属性中的驱动程序
SQLException failure=null;
用于(驱动程序:驱动程序){
试一试{
连接连接=驱动程序连接(url);
如果(conn!=null)
返回连接;
}捕获(SQLException sqle){
//可能未尝试连接到正确的驱动程序
if(failure==null)
failure=sqle;
}
}
//如果我们到了这里,没有司机能接通
if(失败!=null)
投掷失败;
else//没有连接,但没有司机投诉
抛出新的SQLException(“找不到URL的驱动程序”+URL);
}
更新: (代码示例已更新)

OpenJDK似乎可以容忍驱动程序对其无法识别的协议返回null的情况,也可以容忍驱动程序对其无法识别的协议抛出异常的情况


我认为OpenJDK永远不应该抛出直接来自驱动程序的异常,如果找不到URL的驱动程序,则总是抛出新的SQLException。

这听起来像Informix驱动程序中的一个bug(但充其量只是个小bug)。一个表现良好的JDBC驱动程序需要遵循(emphasis mine)中定义的期望:

尝试建立到给定URL的数据库连接。司机 如果意识到它是错误类型的驱动程序,则应返回“null” 连接到给定的URL。这将是常见的,就像JDBC驱动程序 管理员被要求连接到给定的URL,并将URL传递给每个URL 依次加载驱动程序

如果驱动程序是正确的,那么驱动程序应该抛出SQLException 连接到给定URL,但无法连接到数据库

java.sql.DriverManager.getConnection
将逐个查询所有注册驱动程序的
connect
方法。如果驱动程序返回
null
,它将继续使用下一个驱动程序。如果驱动程序返回连接,则该连接将返回给调用方。如果所有驱动程序都返回
null
,则抛出
SQLException
,并显示“找不到[url]的合适驱动程序”消息

如果驱动程序抛出
SQLException
,则保留最后抛出的异常,并且驱动程序管理器将继续处理下一个驱动程序。如果所有其他驱动程序以
null
拒绝连接尝试,则将引发最后一个异常,而不是“无合适的驱动程序…”例外