Java informix jdbc 卡住连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21572185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
informix jdbc stuck connecting
提问by xacy
I'm trying to connect to a Informix database server with jdbc using the standard way :
我正在尝试使用标准方式使用 jdbc 连接到 Informix 数据库服务器:
connection = DriverManager.getConnection("jdbc:informix-sqli://"+ip+
/"+sid+":INFORMIXSERVER="+server+";user="+user+";password="+pass+"");
But it keeps trying to connect and does not throw a error message (I suppose it tries to connect because it does not show anything). I'm using IBM Informix driver 4.10.00.1534 and Java 1.7. I have been using this method to connect to Informix servers until now, in fact it only fails with one server. I can connect to this server through Informix clients with odbc but it keeps failing with jdbc with no error message.
但它不断尝试连接并且不会抛出错误消息(我想它尝试连接是因为它没有显示任何内容)。我使用的是 IBM Informix 驱动程序 4.10.00.1534 和 Java 1.7。到目前为止,我一直使用这种方法连接到 Informix 服务器,实际上它只在一台服务器上失败。我可以使用 odbc 通过 Informix 客户端连接到该服务器,但使用 jdbc 一直失败,没有错误消息。
Is there any method to verbose the jdbc connection? Any suggestion about why it fails?
有什么方法可以详细说明 jdbc 连接吗?关于它为什么失败的任何建议?
UPDATE: The sqlidebug trace:
更新: sqlidebug 跟踪:
C->S (4)
SQ_VERSION
SQ_EOT
S->C (14)
SQ_VERSION
"7.31.TD6" [8]
SQ_EOT
C->S (66)
SQ_INFO
INFO_ENV
Name Length = 12
Value Length = 8
"DBTIME"="%d/%M/%Y"
"DBTEMP"="/tmp"
"SUBQCACHESZ"="10"
INFO_DONE
SQ_EOT
S->C (2)
SQ_EOT
C->S (16)
SQ_DBOPEN
"database" [8]
NOT EXCLUSIVE
SQ_EOT
S->C (28)
SQ_DONE
Warning..: 0x15
# rows...: 0
rowid....: 0
serial id: 0
SQ_COST
estimated #rows: 1
estimated I/O..: 1
SQ_EOT
C->S (78)
SQ_PREPARE
# values: 0
CMD.....: "select site from informix.systables where tabname = ' GL_COLLATE'" [65]
SQ_NDESCRIBE
SQ_WANTDONE
SQ_EOT
And the jdbctrace.log says:
jdbctrace.log 说:
trying com.informix.jdbc.IfxDriver
SQLWarning: reason(Database selected) SQLState(01I04)
SQLWarning: reason(Float to decimal conversion has been used) SQLState(01I05)
SQLWarning: reason(Database has transactions) SQLState(01I01)
SQLWarning: reason(Database selected) SQLState(01I04)
SQLWarning: reason(Database has transactions) SQLState(01I01)
SQLWarning: reason(Database selected) SQLState(01I04)
采纳答案by Micha? Niklas
Try to run code that connects do Informix database but also shows full exception info and create trace files. One trace file is for JDBC, one is for Informix. Change URL to database, username and password, and run it. You will probably see the problem on screen or in trace file:
尝试运行连接到 Informix 数据库但也显示完整异常信息并创建跟踪文件的代码。一个跟踪文件用于 JDBC,一个用于 Informix。将 URL 更改为数据库、用户名和密码,并运行它。您可能会在屏幕或跟踪文件中看到问题:
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
class informix_trace
{
public static void main(String[] args)
{
try
{
Class.forName("com.informix.jdbc.IfxDriver");
FileWriter fwTrace = new FileWriter("c:\JDBCTrace.log");
PrintWriter pwTrace = new PrintWriter(fwTrace);
DriverManager.setLogWriter(pwTrace);
String debug_url = "SQLIDEBUG=C:\sqlidebug.trace";
String url = "jdbc:informix-sqli://1.2.3.4:9088/test_db:informixserver=ol_testifx;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250;" + debug_url
Connection connection = DriverManager.getConnection(url, "user", "passwd");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT FIRST 1 DBINFO('version','full') FROM systables;");
while (resultSet.next())
System.out.println(resultSet.getObject(1));
}
catch (Exception e)
{
e.printStackTrace();
}
}
} // class informix_trace
Informix trace file will be with some postfix (timestamp or similar info) and in my case it was something like sqlidebug.trace1391758523500.0
. It is binary but you can analyze it using sqliprt
utility.
Informix 跟踪文件将带有一些后缀(时间戳或类似信息),就我而言,它类似于sqlidebug.trace1391758523500.0
. 它是二进制的,但您可以使用sqliprt
实用程序对其进行分析。
Example of my session with wrong database name:
我使用错误数据库名称的会话示例:
c:\>sqliprt sqlidebug.trace1391758523500.0
SQLIDBG Version 1
...
S->C (12)
SQ_ERR
SQL error..........: -329
ISAM/RSAM error....: -111
Offset in statement: 0
Error message......: "" [0]
SQ_EOT
In JDBCTrace.log
I can found more interesting info (I see it also on my screen):
在JDBCTrace.log
我可以找到更多有趣的信息(我也在我的屏幕上看到它):
SQLState(IX000) vendor code(-111)
java.sql.SQLException: ISAM error: no record found.
at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:413)
at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3412)
at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2324)
....
at java.sql.DriverManager.getConnection(Unknown Source)
at informix_trace.main(informix_trace.java:20)
getConnection failed: java.sql.SQLException: No database found or wrong system privileges.
(I have translated it from Polish so it can be little different)
(我是从波兰语翻译过来的,所以可能有点不同)
回答by Micha? Niklas
My suggestion is to:
我的建议是:
- build ConnectString and show us its full content, this way we will see if in
ip
there is only IP address or if it is with port number instead of adding username and password to ConnectString use 3 parameter version of
getConnection()
just like:getConnection("jdbc:informix-sqli://169.0.5.10:9088/test_db:informixserver=ol_test;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250", username, password)
- 构建 ConnectString 并向我们展示其完整内容,这样我们将看到
ip
其中是否只有 IP 地址或是否带有端口号 而不是将用户名和密码添加到 ConnectString 使用 3 参数版本,
getConnection()
就像:getConnection("jdbc:informix-sqli://169.0.5.10:9088/test_db:informixserver=ol_test;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250", username, password)
(of course set your own locale instead of my Polish locale)
(当然设置您自己的语言环境而不是我的波兰语语言环境)
To spy network traffic use tools like Wireshark. Start capturing ip traffic to your Informix database. In my case Wireshark rule is:
要监视网络流量,请使用 Wireshark 等工具。开始捕获到 Informix 数据库的 ip 流量。就我而言,Wireshark 规则是:
ip.addr == 169.0.5.10
If I set up wrong IP Wireshark will display "Destination unreachable".
如果我设置了错误的 IP Wireshark 将显示“目标无法访问”。
You can also see someting using netstat:
您还可以使用 netstat 查看某些内容:
c:\>netstat -an | grep 9088
TCP 169.0.1.126:4295 169.0.5.10:9088 TIME_WAIT
It was when my application stopped working.
那是我的应用程序停止工作的时候。
In case of error (wrong IP port) I see:
如果出现错误(错误的 IP 端口),我会看到:
c:\>netstat -an | grep 9089
TCP 169.0.1.126:4398 169.0.5.10:9089 SYN_SENT
回答by hd1
IBM says that: From version 3.00.JC1 of IBM? Informix? JDBC Driver onwards, debug drivers are no longer shipped.
Informix JDBC Driver now supports SQLIDEBUG. You no longer need to set values for TRACE, TRACEFILE or PROTOCOLTRACE, PROTOCOLTRACEFILE. You only need to set SQLIDEBUG.
and the page goes on to outline the steps you need to create a trace. Copying:
IBM说:From version 3.00.JC1 of IBM? Informix? JDBC Driver onwards, debug drivers are no longer shipped.
Informix JDBC Driver now supports SQLIDEBUG. You no longer need to set values for TRACE, TRACEFILE or PROTOCOLTRACE, PROTOCOLTRACEFILE. You only need to set SQLIDEBUG.
并且该页面继续概述创建跟踪所需的步骤。复制:
Set the CLASSPATH to the Informix JDBC Driver package.
c:\Infx\Java>set CLASSPATH=C:\infx\JDBC3.00JC3\lib\ifxjdbc.jar;C:\infx\JDBC3.00JC3\lib\ifxjdbcx.jar;.
Compile simple.java
c:\Infx\Java>javac simple.java
Ensure that SQLIDEBUG is set correctly
c:\Infx\Java>grep SQLIDEBUG simple.java
conn=DriverManager.getConnection("jdbc:informix-sqli://irk:1526/sysmaster:INFORMIXSERVER=irk940;USER=informix; PASSWORD=ximrofni;SQLIDEBUG=C:\infx\java\trace");Note: SQLIDEBUG is set in the connection string. It points to where the trace file will be found with a certain format i.e. trace.xxxxxxx
Remove or move all other trace files
c:\Infx\Java>del trace*
Run java.simple
c:\Infx\Java>java simple systables syscolumns ... ... oledbordinals
Then locate the trace file
c:\Infx\Java>dir trace* Volume in drive C has no label. Volume Serial Number is B823-46D8
Directory of c:\Infx\Java
04/04/2006 14:12 20,560 trace1144156355642.0 1 File(s) 20,560 bytes 0 Dir(s) 4,067,995,648 bytes free
c:\Infx\Java>
You will be able to see that a trace file has been created however you will not be able to read the file.
Send the trace file to your local technical support office for analysis.
将 CLASSPATH 设置为 Informix JDBC 驱动程序包。
c:\Infx\Java>set CLASSPATH=C:\infx\JDBC3.00JC3\lib\ifxjdbc.jar;C:\infx\JDBC3.00JC3\lib\ifxjdbcx.jar;。
编译 simple.java
c:\Infx\Java>javac simple.java
确保 SQLIDEBUG 设置正确
c:\Infx\Java>grep SQLIDEBUG simple.java
conn=DriverManager.getConnection("jdbc:informix-sqli://irk:1526/sysmaster:INFORMIXSERVER=irk940;USER=informix;PASSWORD=ximrofni;SQLIDEBUG=C:\ infx\java\trace");注意:SQLIDEBUG 在连接字符串中设置。它指向可以找到特定格式的跟踪文件的位置,即 trace.xxxxxxx
删除或移动所有其他跟踪文件
c:\Infx\Java>del 跟踪*
运行 java.simple
c:\Infx\Java>java simple systables syscolumns ... ... oledbordinals
然后找到跟踪文件
c:\Infx\Java>dir trace* 驱动器 C 中的卷没有标签。卷序列号为 B823-46D8
c:\Infx\Java 目录
04/04/2006 14:12 20,560 trace1144156355642.0 1 File(s) 20,560 bytes 0 Dir(s) 4,067,995,648 bytes free
c:\Infx\Java>
您将能够看到已创建跟踪文件,但您将无法读取该文件。
将跟踪文件发送到您当地的技术支持办公室进行分析。
Of course, if you're not using Version 3.00.JC1 of the Informix drivers, ignore the above and follow a different set of instructions; again duplicated for your convenience:
当然,如果您不使用版本 3.00.JC1 的 Informix 驱动程序,请忽略以上内容并遵循不同的说明;为了您的方便再次复制:
To turn on tracing, specify the environment variables TRACE, TRACEFILE, PROTOCOLTRACE, and PROTOCOLTRACEFILE in the database URL or the property list when you establish a connection to an Informix database or database server. TRACE can be set to one of the following levels:
- Tracing not enabled. This is the default value.
- Traces the entry and exit points of methods.
- Same as Level 1, plus generic error messages are also traced.
- Same as Level 2, plus data variables are also traced. TRACEFILE Specifies the full pathname of the operating system file on the client computer to which the TRACE messages are written.
PROTOCOLTRACE traces the SQLI protocol messages sent between your Java program and the Informix database server.
Can be set to the following levels:
- Protocol tracing not enabled. This is the default value.
- Traces message IDs.
- Same as Level 1, plus the data in the message packets are also traced. PROTOCOLTRACFILE specifies the full pathname of the operating system file on the client computer to which the PROTOCOLTRACE messages are written.
要打开跟踪,请在建立与 Informix 数据库或数据库服务器的连接时在数据库 URL 或属性列表中指定环境变量 TRACE、TRACEFILE、PROTOCOLTRACE 和 PROTOCOLTRACEFILE。TRACE 可以设置为以下级别之一:
- 未启用跟踪。这是默认值。
- 跟踪方法的入口和出口点。
- 与级别 1 相同,此外还会跟踪一般错误消息。
- 与级别 2 相同,还跟踪数据变量。TRACEFILE 指定客户端计算机上写入 TRACE 消息的操作系统文件的完整路径名。
PROTOCOLTRACE 跟踪在 Java 程序和 Informix 数据库服务器之间发送的 SQLI 协议消息。
可以设置为以下级别:
- 未启用协议跟踪。这是默认值。
- 跟踪消息 ID。
- 与Level 1 相同,另外还跟踪消息包中的数据。PROTOCOLTRACFILE 指定客户端计算机上写入 PROTOCOLTRACE 消息的操作系统文件的完整路径名。
Hope that helps
希望有帮助
回答by Bartek
回答by Vishwanath Hiremath
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import com.informix.*;
public class DBConnect {
static String url="jdbc:informix-sqli://host_name:port/database_name:INFORMIXSERVER=server;user=username;password=password";
public static void main(String [] args){
try {
Class.forName("com.informix.jdbc.IfxDriver");
}catch (Exception e){
System.out.println("ERROR: failed to load Informix JDBC driver.");
e.printStackTrace();
return;
}
try{
DriverManager.registerDriver((com.informix.jdbc.IfxDriver)Class.forName("com.informix.jdbc.IfxDriver").newInstance());
}catch(Exception ex){
System.out.println("Driver is not Registered");
}
try{
Connection conn = DriverManager.getConnection(url);
System.out.println("Connection Successful");
}catch (SQLException e){
System.out.println("ERROR: failed to connect!");
System.out.println("ERROR: " + e.getMessage());
e.printStackTrace();
return;
}
}
}
For more info go through [this book] (http://www.cursor-distribution.de/aktuell.11.70.xC6/documentation/ids_jdbc_bookmap.pdf)
有关更多信息,请阅读 [本书] ( http://www.cursor-distribution.de/aktuell.11.70.xC6/documentation/ids_jdbc_bookmap.pdf)
回答by ron190
The problem I encountered was that Informix was listening on local IPv6 address on port 7360, command netstat -a
was displaying this format :
我遇到的问题是 Informix 正在侦听端口 7360 上的本地 IPv6 地址,命令netstat -a
显示以下格式:
TCP [feab::11ab:78ab:efab:8aab%17]:7360 myhostname:0 LISTENING
Therefore my jdbc connection was always failing until I figured out I should have use the IPv6 address in the URL :
因此,我的 jdbc 连接总是失败,直到我发现我应该在 URL 中使用 IPv6 地址:
jdbc:informix-sqli://fe80::1125:78c0:ef17:8ab5%17:7360:user=informix;password=test;INFORMIXSERVER=ol_informix1210_2
jdbc:informix-sqli://fe80::1125:78c0:ef17:8ab5%17:7360:user=informix;password=test;INFORMIXSERVER=ol_informix1210_2
You can test that the connection is working with this simple script :
您可以使用这个简单的脚本测试连接是否正常工作:
/***************************************************************************
*
* Title: SimpleConnection.java
*
* Description: Demo a connection to a server (no database specified)
*
* An example of running the program:
*
* java SimpleConnection
* 'jdbc:informix-sqli://myhost:1533:user=<username>;password=<password>'
*
* Expected result:
*
* >>>Simple Connection test.
* URL = "jdbc:informix-sqli://myhost:1533:user=<username>;password=<password>"
* >>>End of Simple Connection test.
*
***************************************************************************
*/
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SimpleConnection {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("FAILED: connection URL must be provided in order to run the demo!");
return;
}
String url = args[0];
String testName = "Simple Connection";
Connection conn = null;
System.out.println(">>>" + testName + " test.");
System.out.println("URL = \"" + url + "\"");
try {
Class.forName("com.informix.jdbc.IfxDriver");
} catch (Exception e) {
System.out.println("FAILED: failed to load Informix JDBC driver.");
}
try {
PrintWriter out = new PrintWriter(System.out, true);
DriverManager.setLogWriter(out);
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
System.out.println("FAILED: failed to connect!");
}
try {
conn.close();
} catch (SQLException e) {
System.out.println("FAILED: failed to close the connection!");
}
System.out.println(">>>End of " + testName + " test.");
}
}