19

I'm trying to set a network time-out my Oracle database Connection in Java. However, I'm getting an error. Below is sample code and it's respective exception.

try{
    conn = new Database("oracle").connect();
    conn.setNetworkTimeout(null, 30000); //I don't have an Executor, so the field is set to null
    System.out.println(Switch.date() + " -> Database Connection Initialized");
}
catch(SQLException ex){
    Logger.getLogger(Switch.class.getName()).log(Level.SEVERE, null, ex);
}

The Exception I'm getting is:

Exception in thread "main" java.lang.AbstractMethodError:oracle.jdbc.driver.T4CConnection.setNetworkTimeout(Ljava/util/concurrent/Executor;I)V
   at ke.co.smart.Switch.<init>(Switch.java:524)
   at ke.co.smart.Switch.main(Switch.java:161)
Java Result: 1

I believe it has to do with a method being abstract (read AbstractMethodError). What could probably cause this error as I have only implemented the method which I think is already defined within Java, and thus, does not refuse to compile.

N.B.: Java does not allow compilation of concrete classes if there are abstract methods.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Patrick W
  • 1,485
  • 4
  • 19
  • 27
  • What is the version of the Oracle driver? Maybe a newer version implements that method. (note: the numbers in the file name "ojdbc6" or "ojdbc5" are **not** the driver version). –  Sep 16 '13 at 09:07
  • If you really want to solve problems with DCD(dead connection detection) you should switch to OCI drivers and configure it on OCI level (in sqlnet.ora). The "best" way is to use TCP keepalive technique. But this needs assistance of DBAs and Unix admins. – ibre5041 Jul 28 '15 at 14:20

3 Answers3

27

setNetworkTimeout() was introduced in JDBC 4.1 and was not present in JDBC 4.0.

You will want ojdbc7 since JDBC 4.1 only came in with Java 7 if you want to use setNetworkTimeout() method.

The underlying issue is that adding methods to interfaces in later specifications can cause older implementations of those interfaces to break with errors. One of the new features of the upcoming Java 8, default methods, will hopefully make this slightly less of a problem.


Apparently there is also a JDBC driver property for Oracle that can modify socket timeouts.

You can also try using this Oracle JDBC property to set the socket timeout if you are using the thin driver:

Properties props = new Properties();
props.setProperty("user", "dbuser");
props.setProperty("password", "dbpassword");
props.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CONNECT_TIMEOUT, "2000");

Connection con = DriverManager.getConnection("<JDBC connection string>", props);
prunge
  • 22,460
  • 3
  • 73
  • 80
  • 1
    Where do you find the JDBC 4.1 driver or how can I be sure I have it? I presume http://www.oracle.com/technetwork/database/features/jdbc/jdbc-drivers-12c-download-1958347.html but it's not written 4.1. – Adrien Feb 02 '14 at 22:36
  • @Adrien For Oracle, the latest and greatest drivers with JDBC 4.1 support are [here](http://www.oracle.com/technetwork/database/features/jdbc/jdbc-drivers-12c-download-1958347.html). – prunge Feb 03 '14 at 00:21
  • is this "2000" milisecundum, or secundum? – victorio Dec 15 '14 at 12:55
  • The [documentation](http://docs.oracle.com/cd/E18283_01/appdev.112/e13995/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_THIN_READ_TIMEOUT) says: > Timeout is in milliseconds. – prunge Dec 16 '14 at 05:06
  • 10
    For those who want to add the connection property to the connection url: `jdbc:oracle:thin:@host:1521:DB:oracle.net.CONNECT_TIMEOUT=2000;` – andy Jan 28 '16 at 19:48
  • @Scadge, same here. I don't remember where I found it, sorry. May be in the configuration of a customer's application. – andy Mar 17 '18 at 23:05
  • Hi @andy, how can i add `oracle.net.CONNECT_TIMEOUT` in SpringBoot's application.properties? spring.datasource.url will not accept `jdbc:oracle:thin:@host:1521:DB:oracle.net.CONNECT_TIMEOUT=2000;` as the part after the `thin` need to be in the format `host:port:sid` – jumping_monkey Dec 16 '19 at 06:26
  • 1
    @jumping_monkey, try this: `spring.datasource.hikari.data-source-properties.oracle.net.CONNECT_TIMEOUT=2000` – andy Dec 16 '19 at 17:34
  • There's also an `OracleConnection.CONNECTION_PROPERTY_THIN_READ_TIMEOUT = "oracle.jdbc.ReadTimeout"` – stephan f Sep 21 '21 at 12:21
2

This is a classic case of software evolution. The JDBC provider has not given the implementation of the method yet in the jar you are using. Looks like your JDBC library is quite old and you may try the latest one.

Download latest one from here: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html

Try this approach taken from here:

conn.setNetworkTimeout(Executors.newFixedThreadPool(numThreads), yourTimeout);
Community
  • 1
  • 1
Gyanendra Dwivedi
  • 5,511
  • 2
  • 27
  • 53
  • The issue is not the age of the jdbc library, I'm using ojdbc6 which is an implementation of JDBC 4.0, and therefore the newest library. – Patrick W Sep 16 '13 at 07:45
  • It is not necessary that ojdbc6 would have implemented whole JDBC 4.0 specification; may be one of the minor version of that have implemented that. Why not give it a try to download the latest one, more likely it will solve your problem. – Gyanendra Dwivedi Sep 16 '13 at 07:50
  • No luck, just tried with that with no success, results in same error. – Patrick W Sep 16 '13 at 07:58
  • @patwanjau when you execute the JDBC jar file, which driver version it reports? – ibre5041 Jul 29 '15 at 07:12
1

From the Oracle's documentation: "setNetworkTimeout throws an SQLException if: a database access error occurs, this method is called on a closed connection, the executor is NULL". The latter seems your case.

Gabe
  • 5,997
  • 5
  • 46
  • 92