Permalink
Browse files

fix: avoid reflective access to TimeZone.defaultTimeZone in Java 9+ (#…

…1002)

closes #986
  • Loading branch information...
vlsi committed Nov 28, 2017
1 parent d74386d commit fd0eeee8f123b1355b523425a1e11fdd59b057a5
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2017, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.core;

public enum JavaVersion {
// Note: order is important,
v1_6,
v1_7,
v1_8,
other;

private static final JavaVersion RUNTIME_VERSION = from(System.getProperty("java.version"));

/**
* Returns enum value that represents current runtime. For instance, when using -jre7.jar via Java
* 8, this would return v18
*
* @return enum value that represents current runtime.
*/
public static JavaVersion getRuntimeVersion() {
return RUNTIME_VERSION;
}

/**
* Java version string like in {@code "java.version"} property
*
* @param version string like 1.6, 1.7, etc
* @return JavaVersion enum
*/
public static JavaVersion from(String version) {
// Minimum supported is Java 1.6
if (version.startsWith("1.6")) {
return v1_6;
}
if (version.startsWith("1.7")) {
return v1_7;
}
if (version.startsWith("1.8")) {
return v1_8;
}
return other;
}
}
@@ -6,6 +6,7 @@
package org.postgresql.jdbc;

import org.postgresql.PGStatement;
import org.postgresql.core.JavaVersion;
import org.postgresql.core.Oid;
import org.postgresql.core.Provider;
import org.postgresql.util.ByteConverter;
@@ -85,12 +86,16 @@
// This saves the creation of a clone everytime, and the memory associated to all these clones.
Field tzField;

This comment has been minimized.

@peterlindstrom234

peterlindstrom234 Jan 12, 2018

Why do you "save" the Field anyway, instead of the actual default timezone value?

try {
tzField = TimeZone.class.getDeclaredField("defaultTimeZone");
tzField.setAccessible(true);
TimeZone defaultTz = TimeZone.getDefault();
Object tzFromField = tzField.get(null);
if (defaultTz == null || !defaultTz.equals(tzFromField)) {
tzField = null;
tzField = null;
// Avoid reflective access in Java 9+
if (JavaVersion.getRuntimeVersion().compareTo(JavaVersion.v1_8) <= 0) {

This comment has been minimized.

@peterlindstrom234

peterlindstrom234 Jan 12, 2018

It looks like nothing is done with Java 9. Does that mean the driver will run slower?

tzField = TimeZone.class.getDeclaredField("defaultTimeZone");
tzField.setAccessible(true);
TimeZone defaultTz = TimeZone.getDefault();
Object tzFromField = tzField.get(null);
if (defaultTz == null || !defaultTz.equals(tzFromField)) {
tzField = null;
}
}
} catch (Exception e) {
tzField = null;
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2017, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.test.core;

import org.postgresql.core.JavaVersion;

import org.junit.Assert;
import org.junit.Test;

public class JavaVersionTest {
@Test
public void testGetRuntimeVersion() {
String currentVersion = System.getProperty("java.version");
String msg = "java.version = " + currentVersion + ", JavaVersion.getRuntimeVersion() = "
+ JavaVersion.getRuntimeVersion();
System.out.println(msg);
if (currentVersion.startsWith("1.8")) {
Assert.assertEquals(msg, JavaVersion.v1_8, JavaVersion.getRuntimeVersion());
}
}
}
@@ -9,6 +9,7 @@
import org.postgresql.core.ReturningParserTest;
import org.postgresql.core.v3.V3ParameterListTests;
import org.postgresql.jdbc.DeepBatchedInsertStatementTest;
import org.postgresql.test.core.JavaVersionTest;
import org.postgresql.test.core.NativeQueryBindLengthTest;
import org.postgresql.test.util.ExpressionPropertiesTest;
import org.postgresql.test.util.LruCacheTest;
@@ -25,6 +26,7 @@
@RunWith(Suite.class)
@Suite.SuiteClasses({
ANTTest.class,
JavaVersionTest.class,

DriverTest.class,
ConnectionTest.class,

0 comments on commit fd0eeee

Please sign in to comment.