问题
I'm trying to connect to a Informix database server with jdbc using the standard way :
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.
Is there any method to verbose the jdbc connection? Any suggestion about why it fails?
UPDATE: The sqlidebug trace:
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:
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)
回答1:
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:
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.
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):
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)
回答2:
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)
(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:
ip.addr == 169.0.5.10
If I set up wrong IP Wireshark will display "Destination unreachable".
You can also see someting using 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:
c:\>netstat -an | grep 9089
TCP 169.0.1.126:4398 169.0.5.10:9089 SYN_SENT
回答3:
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:
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.
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:
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.
Hope that helps
回答4:
- try different jdbc version
- check NETTYPE configuration parameter and compare it with current number of informix sessions
- dump java thread states (kill -3 ) when jdbc connection hangs
回答5:
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)
回答6:
The problem I encountered was that Informix was listening on local IPv6 address on port 7360, command netstat -a
was displaying this format :
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: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.");
}
}
来源:https://stackoverflow.com/questions/21572185/informix-jdbc-stuck-connecting