我遇到了一个非常奇怪的问题这是一个非常简单的JDBC连接到Oracle数据库的用法
OS: Ubuntu
Java Version: 1.5.0_16-b02
1.6.0_17-b04
Database: Oracle 11g Release 11.1.0.6.0
Run Code Online (Sandbox Code Playgroud)
当我使用jar文件时
OJDBC14.jar它每次都连接到数据库当我使用jar文件时
OJDBC5.jar它连接了一些时间,有时它会抛出一个错误(如下所示)如果我用Java 6重新编译并使用
OJDBC6.jar我获得相同的结果如OJDBC5.jar
我需要JODB5.jar中的特定功能,这些功能在OJDBC14.jar中不可用
有任何想法吗
错误
> Connecting to oracle
java.sql.SQLException: Io exception: Connection reset
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:74)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:494)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:411)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:474)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at TestConnect.main(TestConnect.java:13)
Run Code Online (Sandbox Code Playgroud)
码
以下是我正在使用的代码
import java.io.*;
import java.sql.*;
public class TestConnect {
public static void main(String[] args) {
try {
System.out.println("Connecting to oracle");
Connection con=null;
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection(
"jdbc:oracle:thin:@172.16.48.100:1535:sample",
"JOHN",
"90009000");
System.out.println("Connected to oracle");
con.close();
System.out.println("Goodbye");
} catch(Exception e) { e.printStackTrace(); }
}
}
Run Code Online (Sandbox Code Playgroud)
Dro*_*ona 91
在一些OTN论坛(https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989)中提供了解决此问题的解决方案.但是,没有解释问题的根本原因.以下是我尝试解释问题的根本原因.
Oracle JDBC驱动程序以安全的方式与Oracle服务器通信.驱动程序使用 java.security.SecureRandom类来收集熵以保护通信.此类依赖于本机平台支持来收集熵.
熵是由操作系统或应用程序收集/生成的随机性,用于加密或需要随机数据的其他用途.这种随机性通常是从硬件噪声源,硬件噪声,音频数据,鼠标移动或专门提供的随机性生成器中收集的.内核收集熵并存储它是一个熵池,并通过特殊文件/ dev/random和/ dev/urandom使随机字符数据可供操作系统进程或应用程序使用.
从/ dev/random读取使用所请求的比特/字节量来消耗熵池,从而提供加密操作中经常需要的高度随机性.在这种情况下,如果熵池被完全耗尽并且没有足够的熵,则对/ dev/random块进行读取操作,直到收集到额外的熵.因此,从/ dev/random读取的应用程序可能会阻塞一段随机时间.
与上述相反,从/ dev/urandom读取不会阻止.从/ dev/urandom读取也会消耗熵池,但是当缺少足够的熵时,它不会阻塞,而是重用来自部分读取的随机数据的位.据说这很容易受到密码分析攻击.这是一种理论上的可能性,因此不鼓励从/ dev/urandom读取以在加密操作中收集随机性.
的java.security.SecureRandom中类,默认情况下,从读出的/ dev /随机文件,因此有时对的时间随机时段块.现在,如果读取操作没有返回所需的时间,则Oracle服务器会超时客户端(在本例中为jdbc驱动程序)并通过从其末端关闭套接字来中断通信.从阻塞调用返回后尝试恢复通信的客户端遇到IO异常.此问题可能在任何平台上随机发生,尤其是从硬件噪声中收集熵的情况.
正如OTN论坛中所建议的,这个问题的解决方案是覆盖java.security.SecureRandom类的默认行为,以使用来自/ dev/urandom的非阻塞读取而不是来自/ dev/random的阻塞读取.这可以通过将以下系统属性-Djava.security.egd = file:/// dev/urandom添加到JVM来完成.虽然这对于像JDBC驱动程序这样的应用程序来说是一个很好的解决方案,但对于执行密码密钥生成等核心加密操作的应用程序来说,这是不鼓励的.
其他解决方案可以是使用可用于平台的不同随机播种器实现,其不依赖于硬件噪声来收集熵.有了这个,您可能仍需要覆盖java.security.SecureRandom的默认行为.
增加Oracle服务器端的套接字超时也可以是一种解决方案,但在尝试此操作之前,应从服务器的角度评估副作用.
小智 17
我面临着同样的问题.使用Windows Vista我无法重现问题但在Ubuntu上我不断重现'连接重置' - 错误.
我找到了 http://forums.oracle.com/forums/thread.jspa?threadID=941911&tstart=0&messageID=3793101
据该论坛上的用户说:
我和甲骨文开了一张票,这就是他们告诉我的.
java.security.SecureRandom是sun提供的标准API.在这个类提供的各种方法中,void nextBytes(byte [])是一个.该方法用于生成随机字节.Oracle 11g JDBC驱动程序使用此API在登录期间生成随机数.使用Linux的用户遇到了SQLException("Io exception:Connection reset").
这个问题有两个问题
当调用SecureRandom.nextBytes(byte [])时,JVM会尝试列出/ tmp(或-Djava.io.tmpdir设置的备用tmp目录)中的所有文件.如果文件数量很大,则该方法需要很长时间才能响应,从而导致服务器超时
方法void nextBytes(byte [])在Linux上使用/ dev/random,在缺少随机数生成硬件的某些机器上,操作速度降低到使整个登录过程停止的程度.最终用户遇到SQLException("Io exception:Connection reset")
如果底层操作系统是在故障硬件上运行的Linux,则升级到11g的用户可能会遇到此问题.
原因尚未确切地确定原因.它可能是您硬件中的问题,也可能是由于某种原因软件无法从dev/random读取的事实
解决方案更改应用程序的设置,以便将下一个参数添加到java命令:
-Djava.security.egd =文件是:/ dev /../开发/ urandom的
我们在java.security文件中进行了此更改,它已经摆脱了错误.
这解决了我的问题.
“连接重置”错误消息通常表示在尝试创建连接(握手)期间,另一端已中止连接。这有很多可能的原因。JDBC驱动程序中的错误,数据库侧的超时,数据库的重新启动,可用的连接用尽了数据库,网络质量差,病毒扫描程序/防火墙/代理错误等。
由于它是间歇性发生的,因此JDBC驱动程序中的错误可能会或多或少地被排除。遗留下来的可能原因。我建议从查找数据库服务器的日志开始。
很难说,但我是否会检查 JDBC 驱动程序的实际版本。确保它是 11.1.0.6。
Oracle 不在文件名中包含数据库版本。因此,11.2 的驱动程序与 11.1 的驱动程序名称完全相同 - ojdbc5.jar。我将提取驱动程序 jar 文件,并找到 MANIFEST.MF 文件,这将包含一些版本信息。确保 JDBC 驱动程序的版本与数据库的版本匹配。我怀疑这可能是版本问题,因为Oracle的11.1.0.6下载页面上没有名为ojdbc14.jar的jar文件。
如果版本匹配 - 我没有主意了:)
| 归档时间: |
|
| 查看次数: |
108162 次 |
| 最近记录: |