Search code examples
javasocket-timeout-exceptionjtopen

JTOpen ProgramCall Socket Timeout


I'm working on a web app (running on Tomcat) that calls programs on an IBM i (AS/400) using the JTOpen ProgramCall class (com.ibm.as400.access.ProgramCall). My problem is with program calls that take more than 30s to respond, which are triggering a java.net.SocketTimeoutException: Read timed out exception.

There is a setTimeout() method available for this class, but it doesn't seem to have an effect on the socket timeout. I've also checked my Tomcat configurations and didn't see anything that would cause this behavior.

Does anyone know of a way to alter the timeout for such an implementation?

Code:

pgmCall.setProgram(getCompleteName(), parmList);
initializeAS400TextParameters();

// Run the AS/400 program.
try {
    Trace.setTraceDiagnosticOn(true);
    Trace.setTraceInformationOn(true);
    Trace.setTraceWarningOn(true);
    Trace.setTraceErrorOn(true);
    Trace.setTraceDatastreamOn(true);

    if (pgmCall.run() != true) {
        messageList = pgmCall.getMessageList();
        for (int i = 0; i < messageList.length; i++) {
            log.debug("Error Message " + i + "  " + messageList[i]);
        }
        setCompletionMsg("Program call failed.");
        log.debug("442 Program call failed.");

        return false;
    } else {
        messageList = pgmCall.getMessageList();
        for (int i = 0; i < messageList.length; i++) {
            log.debug("Success Message " + i + "  " + messageList[i]);
        }
        setCompletionMsg("Program called ok.");
        log.debug("452 Program called ok.");

        return true;
    }
} catch (Exception e) {
    // This is where the timeout exception is thrown
    log.debug("Error Running Program: " + e.getMessage() + "  " + e.getLocalizedMessage());
    setCompletionMsg(e.getMessage());
}

Solution

  • Well, after several more hours I've found the solution. Apparently the original developer added a socket timeout parameter to the JDBC connection string - simply removing the parameter did the trick as the default value is 0, or infinite timeout.

    Before:

    String connectionStr = "jdbc:as400://" + systemInfo.getIPAddress() + ":1527" + ";naming=system;socket timeout=30000;thread used=false;errors=full;prompt=false;date format=iso;block size=128;transaction isolation=none;user=" + systemInfo.getUserName() + ";password=" + systemInfo.getPassword();

    After:

    String connectionStr = "jdbc:as400://" + systemInfo.getIPAddress() + ":1527" + ";naming=system;thread used=false;errors=full;prompt=false;date format=iso;block size=128;transaction isolation=none;user=" + systemInfo.getUserName() + ";password=" + systemInfo.getPassword();

    :\