[CONJ-121] Issue with org.mariadb.jdbc.MySQLConnection.setNetworkTimeout Created: 2014-11-12  Updated: 2015-05-22  Resolved: 2014-12-09

Status: Closed
Project: MariaDB Connector/J
Component/s: None
Affects Version/s: 1.1.7
Fix Version/s: 1.1.8

Type: Bug Priority: Minor
Reporter: Ernst Riemer Assignee: Massimo Siani (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to CONJ-156 SecurityManager being used incorrectly Closed

 Description   

Hi there,

We were seeing an issue while using MariaDB 1.1.7 and HikariCP (2.2+) together

I filed a bug here - https://github.com/brettwooldridge/HikariCP/issues/175

Below is a snippet from the conversation from the above github link

Regards

==========================

We will implement a workaround for this, but the issue seems to be caused by a bug in the MariaDB driver.

We call connection.getNetworkTimeout() to determine whether network timeout is supported. If network timeout is not supported, we expect a SQLFeatureNotSupportedException exception (like above) from this call. However, connection.getNetworkTimeout() is simply returning the value 0. Therefore, we are expecting that timeout is supported. Subsequently, we call connection.setNetworkTimeout() and at this point a SQLFeatureNotSupportedException is thrown.

MariaDB, if it does not support setNetworkTimeout() should also throw SQLFeatureNotSupportedException for getNetworkTimeout(). Please open a bug against the MariaDB JDBC driver. As I said, we will implement a workaround, but this is improper behavior from their driver.

Exceptions:

Caused by: java.lang.RuntimeException: Fail-fast during pool initialization
at com.zaxxer.hikari.pool.HikariPool.fillPool(HikariPool.java:505)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:163)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:114)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:78)
... 46 more
Caused by: java.sql.SQLFeatureNotSupportedException: Not yet supported
at org.mariadb.jdbc.internal.SQLExceptionMapper.getFeatureNotSupportedException(SQLExceptionMapper.java:165)
at org.mariadb.jdbc.MySQLConnection.setNetworkTimeout(MySQLConnection.java:1319)
at com.zaxxer.hikari.util.PoolUtilities.setNetworkTimeout(PoolUtilities.java:299)
at com.zaxxer.hikari.pool.HikariPool.addConnection(HikariPool.java:425)
at com.zaxxer.hikari.pool.HikariPool.fillPool(HikariPool.java:504)
... 60 more



 Comments   
Comment by Vladislav Vaintroub [ 2014-11-17 ]

It is a matter of opinion. getNetworkTimeout, as it is documented returns 0 if there is no network timeout (if it is infinite). What is the reason not to suport it if its support is trivial .

OTOH, supporting for setNetworkTimeout is also trivial via socket option (one just needs to make sure to close connections once this timeout fires)

Comment by Brett Wooldridge [ 2014-12-06 ]

One could argue that it is not a matter of opinion. The JavaDoc for setNetworkConnection() in the throws section says it throws:

SQLFeatureNotSupportedException - if the JDBC driver does not support this method

While the JavaDoc for getNetworkTimeout() *does* say it returns 0 when "there is no limit", it also declares:

SQLFeatureNotSupportedException - if the JDBC driver does not support this method

Clearly, returning 0 from a method is trivial, so any driver can trivially "support this method", so what then is the point of declaring that it can throw SQLFeatureNotSupportedException? It seems clear that if a driver does not support the concept of network timeout in general, it is obligated to throw this exception.

In the experience of HikariCP, as a connection pool under which users have placed many many JDBC drivers, this is the first time we have encountered this behavior.

I think it is reasonable for a user calling getNetworkTimeout(), and receiving a valid response, to assume that they can call setNetworkTimeout() without an exception.

Comment by Vladislav Vaintroub [ 2014-12-06 ]

I think you are trying to interpret too much of what JDBC is saying . It is saying 0 means no limit.
Every new method in JDBC 4.0 can throw FeatureNotSupporteException, so it does not mean anything. Specifically it does not mean "if one of any get/set methods throws SQLFeatureNotSupportedException, the other one must do the same". That assumption is wrong in my opinion

I can imagine reasons why getter can work and setter would fail. Imagine a driver that supports timeout, but only at creation time (e.g via "&timeout=1" in connection URL). This timeout cannot be changed at runtime. What should "set" do? fail with SQLFeatureNotSupportedException, IMO. What would "get" do ? return timeout which was set on creation.

Comment by Brett Wooldridge [ 2014-12-06 ]

I can understand your reasoning, and I cannot in earnesty say you are wrong. We at HikariCP in fact "coded around" the issue, so it is no longer causing failures for our users. But given that MariaDB does not support setting a timeout via URL at creation time, or support configuring a network timeout in any way, we would argue that the "more correct" thing would be to throw the exception. Again, that is just our opinion. We're just trying to make MariaDB better.

Comment by Vladislav Vaintroub [ 2014-12-06 ]

I believe that Massimo already fixed that by using network timeouts, so everyone should be happy at last. That intent to improve MariaDB is much appreciated , thanks for that.

The discussion about how to interpret standard is with Massimos fix less relevant, but thinking more about this and your arguments,and I think the "most correct" could the the following interpretation

1. Driver has no idea that timeout it is using and how to set one. Example : JDBC Type 2 driver, that relies on native library which has implicit settings, or something in config file or registry or somesuch.
getNetworkTimeout throws SQLFeatureNotImplemented
setNetworkTimeout does the same

2. "Read-only" Driver knows what timeout it is using, but this timeout cannot be set (MariaDB 1.1.7), or can only be set once, during connection creation, like in my prior example

getNetworkTimeout returns actual timeout
setNetworkTimeout throws Exception

3.Read-write timeout, like in the next version of MariaDB driver

getNetworkTimeout returns actual timeout
setNetworkTimeout sets timeout

This might be more elaborate than the simple "both work or both do not", but it looks right to me

Comment by Brett Wooldridge [ 2014-12-06 ]

Agreed. And it's great to see MariaDB implementing this feature. When used in combination with a (well designed) pool, it can greatly increase application recoverability from network interruptions.

Generated at Thu Feb 08 03:13:19 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.