When I run a java code to connect to Oceanbase and I set the default time zone to UTC or GMT+00:00, an exception will be throwed:
Failed to establish a connection: Could not connect to *****:2881 : (conn=3221584558) The server time_zone 'GMT+08:00' defined in the 'serverTimezone' parameter cannot be parsed by java TimeZone implementation. See java.util.TimeZone#getAvailableIDs() for available TimeZone, depending on your JRE implementation.
java.sql.SQLTransientConnectionException: Could not connect to ******:2881 : (conn=3221584558) The server time_zone 'GMT+08:00' defined in the 'serverTimezone' parameter cannot be parsed by java TimeZone implementation. See java.util.TimeZone#getAvailableIDs() for available TimeZone, depending on your JRE implementation.
at com.oceanbase.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:128)
at com.oceanbase.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:235)
at com.oceanbase.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1644)
at com.oceanbase.jdbc.internal.util.Utils.retrieveProxy(Utils.java:1427)
at com.oceanbase.jdbc.OceanBaseConnection.newConnection(OceanBaseConnection.java:306)
at com.oceanbase.jdbc.Driver.connect(Driver.java:89)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
at com.example.apecloud.DatabaseManager.getConnection(DatabaseManager.java:67)
at com.example.apecloud.DatabaseManager.testConnection(DatabaseManager.java:39)
at com.example.Main.getConn(Main.java:159)
at com.example.Main.main(Main.java:42)
I analyzed the source code, and I believe the issue lies within the sendAlterSessionTimezone function.
private void sendAlterSessionTimezone() throws IOException, SQLException {
this.importedTimeZoneTables = getServerTZTablesImported();
String zoneId = this.importedTimeZoneTables ? TimeZone.getDefault().getID()
: TimeZone.getDefault().toZoneId().getRules().getStandardOffset(Instant.now()).getId();
// when importedTimeZoneTables is
// false: the TIME_ZONE cannot be set to any values that start with "GMT"
// true: only GMT, GMT+0, GMT-0, GMT0 can be accepted
if (zoneId.startsWith("GMT") && (!this.importedTimeZoneTables
|| !zoneId.equalsIgnoreCase("GMT")|| !zoneId.equalsIgnoreCase("GMT+0")
|| !zoneId.equalsIgnoreCase("GMT-0") || !zoneId.equalsIgnoreCase("GMT0"))) {
zoneId = zoneId.substring("GMT".length());
}
writer.startPacket(0);
writer.write(Packet.COM_QUERY);
writer.write(ALTER_SESSION_TIMEZONE_QUERY);
writer.write(zoneId.getBytes());
writer.write('\'');
writer.flush();
}
When the default timezone is UTC, the TimeZone.getDefault().toZoneId().getRules().getStandardOffset(Instant.now()).getId() will return Z, and Z is not a valid timezone for alter session set TIME_ZONE that will throw an exception, unfortunately, this exception message is not been printed, so it is difficult to clearly see where the problem lies.
IMO, this function should check if the zoneId is Z, if yes, convert it to a valid timezone format.
Describe the bug
When I run a java code to connect to Oceanbase and I set the default time zone to
UTC
orGMT+00:00
, an exception will be throwed:Environment
Mac and Java.
Fast reproduce steps
Expected behavior
Connect to the Oceanbase successfully.
Actual behavior
Throw exception.
Additional context
I analyzed the source code, and I believe the issue lies within the
sendAlterSessionTimezone
function.When the default timezone is UTC, the
TimeZone.getDefault().toZoneId().getRules().getStandardOffset(Instant.now()).getId()
will returnZ
, andZ
is not a valid timezone foralter session set TIME_ZONE
that will throw an exception, unfortunately, this exception message is not been printed, so it is difficult to clearly see where the problem lies.IMO, this function should check if the zoneId is
Z
, if yes, convert it to a valid timezone format.