Question

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)
Was it helpful?

Solution

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)

OTHER TIPS

My suggestion is to:

  1. 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
  2. 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

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:

  1. 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;.

  2. Compile simple.java

    c:\Infx\Java>javac simple.java

  3. 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

  4. Remove or move all other trace files

    c:\Infx\Java>del trace*

  5. Run java.simple

    c:\Infx\Java>java simple systables syscolumns ... ... oledbordinals

  6. 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.

  7. 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:

  1. Tracing not enabled. This is the default value.
  2. Traces the entry and exit points of methods.
  3. Same as Level 1, plus generic error messages are also traced.
  4. 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:

  1. Protocol tracing not enabled. This is the default value.
  2. Traces message IDs.
  3. 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

  1. try different jdbc version
  2. check NETTYPE configuration parameter and compare it with current number of informix sessions
  3. dump java thread states (kill -3 ) when jdbc connection hangs
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)

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.");
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top