* Fixed https://github.com/google/gson/issues/1310 Also renamed VersionUtils to more readable abstraction JavaVersion Added support for debian naming convention Using min supported version (6) as the default if JDK version can't be figured out * Moved JavaVersion to an internal package
This commit is contained in:
parent
57085d6212
commit
a6890bbaba
@ -27,12 +27,12 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
import com.google.gson.internal.PreJava9DateFormatProvider;
|
||||
import com.google.gson.internal.bind.util.ISO8601Utils;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.util.VersionUtils;
|
||||
|
||||
/**
|
||||
* This type adapter supports three subclasses of date: Date, Timestamp, and
|
||||
@ -59,7 +59,7 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
|
||||
if (!Locale.getDefault().equals(Locale.US)) {
|
||||
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
|
||||
}
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(DateFormat.DEFAULT, DateFormat.DEFAULT));
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
|
||||
if (!Locale.getDefault().equals(Locale.US)) {
|
||||
dateFormats.add(DateFormat.getDateInstance(style));
|
||||
}
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
dateFormats.add(PreJava9DateFormatProvider.getUSDateFormat(style));
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
|
||||
if (!Locale.getDefault().equals(Locale.US)) {
|
||||
dateFormats.add(DateFormat.getDateTimeInstance(dateStyle, timeStyle));
|
||||
}
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(dateStyle, timeStyle));
|
||||
}
|
||||
}
|
||||
|
90
gson/src/main/java/com/google/gson/internal/JavaVersion.java
Normal file
90
gson/src/main/java/com/google/gson/internal/JavaVersion.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Gson authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.internal;
|
||||
|
||||
/**
|
||||
* Utility to check the major Java version of the current JVM.
|
||||
*/
|
||||
public final class JavaVersion {
|
||||
// Oracle defines naming conventions at http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
|
||||
// However, many alternate implementations differ. For example, Debian used 9-debian as the version string
|
||||
|
||||
private static final int majorJavaVersion = determineMajorJavaVersion();
|
||||
|
||||
private static int determineMajorJavaVersion() {
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
return getMajorJavaVersion(javaVersion);
|
||||
}
|
||||
|
||||
// Visible for testing only
|
||||
static int getMajorJavaVersion(String javaVersion) {
|
||||
int version = parseDotted(javaVersion);
|
||||
if (version == -1) {
|
||||
version = extractBeginningInt(javaVersion);
|
||||
}
|
||||
if (version == -1) {
|
||||
return 6; // Choose minimum supported JDK version as default
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
// Parses both legacy 1.8 style and newer 9.0.4 style
|
||||
private static int parseDotted(String javaVersion) {
|
||||
try {
|
||||
String[] parts = javaVersion.split("[._]");
|
||||
int firstVer = Integer.parseInt(parts[0]);
|
||||
if (firstVer == 1 && parts.length > 1) {
|
||||
return Integer.parseInt(parts[1]);
|
||||
} else {
|
||||
return firstVer;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int extractBeginningInt(String javaVersion) {
|
||||
try {
|
||||
StringBuilder num = new StringBuilder();
|
||||
for (int i = 0; i < javaVersion.length(); ++i) {
|
||||
char c = javaVersion.charAt(i);
|
||||
if (Character.isDigit(c)) {
|
||||
num.append(c);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Integer.parseInt(num.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the major Java version, i.e. '8' for Java 1.8, '9' for Java 9 etc.
|
||||
*/
|
||||
public static int getMajorJavaVersion() {
|
||||
return majorJavaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the application is running on Java 9 or later; and {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isJava9OrLater() {
|
||||
return majorJavaVersion >= 9;
|
||||
}
|
||||
}
|
@ -20,13 +20,13 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
import com.google.gson.internal.PreJava9DateFormatProvider;
|
||||
import com.google.gson.internal.bind.util.ISO8601Utils;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.util.VersionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
@ -62,7 +62,7 @@ public final class DateTypeAdapter extends TypeAdapter<Date> {
|
||||
if (!Locale.getDefault().equals(Locale.US)) {
|
||||
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
|
||||
}
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(DateFormat.DEFAULT, DateFormat.DEFAULT));
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,10 @@
|
||||
*/
|
||||
package com.google.gson.internal.reflect;
|
||||
|
||||
import com.google.gson.util.VersionUtils;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
|
||||
/**
|
||||
* Provides a replacement for {@link AccessibleObject#setAccessible(boolean)}, which may be used to
|
||||
* avoid reflective access issues appeared in Java 9, like {@link java.lang.reflect.InaccessibleObjectException}
|
||||
@ -33,7 +33,7 @@ import java.lang.reflect.AccessibleObject;
|
||||
public abstract class ReflectionAccessor {
|
||||
|
||||
// the singleton instance, use getInstance() to obtain
|
||||
private static final ReflectionAccessor instance = VersionUtils.getMajorJavaVersion() < 9 ? new PreJava9ReflectionAccessor() : new UnsafeReflectionAccessor();
|
||||
private static final ReflectionAccessor instance = JavaVersion.getMajorJavaVersion() < 9 ? new PreJava9ReflectionAccessor() : new UnsafeReflectionAccessor();
|
||||
|
||||
/**
|
||||
* Does the same as {@code ao.setAccessible(true)}, but never throws
|
||||
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Gson authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.util;
|
||||
|
||||
/**
|
||||
* Utility to check the major Java version of the current JVM.
|
||||
*/
|
||||
public class VersionUtils {
|
||||
|
||||
private static final int majorJavaVersion = determineMajorJavaVersion();
|
||||
|
||||
private static int determineMajorJavaVersion() {
|
||||
String[] parts = System.getProperty("java.version").split("[._]");
|
||||
int firstVer = Integer.parseInt(parts[0]);
|
||||
if (firstVer == 1 && parts.length > 1) {
|
||||
return Integer.parseInt(parts[1]);
|
||||
} else {
|
||||
return firstVer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the major Java version, i.e. '8' for Java 1.8, '9' for Java 9 etc.
|
||||
*/
|
||||
public static int getMajorJavaVersion() {
|
||||
return majorJavaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the application is running on Java 9 or later; and {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isJava9OrLater() {
|
||||
return majorJavaVersion >= 9;
|
||||
}
|
||||
}
|
@ -23,7 +23,8 @@ import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import com.google.gson.util.VersionUtils;
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -47,9 +48,9 @@ public class DefaultDateTypeAdapterTest extends TestCase {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
Locale.setDefault(locale);
|
||||
try {
|
||||
String afterYearSep = VersionUtils.isJava9OrLater() ? ", " : " ";
|
||||
String afterYearLongSep = VersionUtils.isJava9OrLater() ? " at " : " ";
|
||||
String utcFull = VersionUtils.isJava9OrLater() ? "Coordinated Universal Time" : "UTC";
|
||||
String afterYearSep = JavaVersion.isJava9OrLater() ? ", " : " ";
|
||||
String afterYearLongSep = JavaVersion.isJava9OrLater() ? " at " : " ";
|
||||
String utcFull = JavaVersion.isJava9OrLater() ? "Coordinated Universal Time" : "UTC";
|
||||
assertFormatted(String.format("Jan 1, 1970%s12:00:00 AM", afterYearSep),
|
||||
new DefaultDateTypeAdapter(Date.class));
|
||||
assertFormatted("1/1/70", new DefaultDateTypeAdapter(Date.class, DateFormat.SHORT));
|
||||
@ -75,7 +76,7 @@ public class DefaultDateTypeAdapterTest extends TestCase {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
Locale.setDefault(Locale.FRANCE);
|
||||
try {
|
||||
String afterYearSep = VersionUtils.isJava9OrLater() ? " à " : " ";
|
||||
String afterYearSep = JavaVersion.isJava9OrLater() ? " à " : " ";
|
||||
assertParsed(String.format("1 janv. 1970%s00:00:00", afterYearSep),
|
||||
new DefaultDateTypeAdapter(Date.class));
|
||||
assertParsed("01/01/70", new DefaultDateTypeAdapter(Date.class, DateFormat.SHORT));
|
||||
@ -87,7 +88,7 @@ public class DefaultDateTypeAdapterTest extends TestCase {
|
||||
new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
|
||||
assertParsed(String.format("1 janvier 1970%s00:00:00 UTC", afterYearSep),
|
||||
new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
|
||||
assertParsed(VersionUtils.isJava9OrLater() ?
|
||||
assertParsed(JavaVersion.isJava9OrLater() ?
|
||||
"jeudi 1 janvier 1970 à 00:00:00 Coordinated Universal Time" :
|
||||
"jeudi 1 janvier 1970 00 h 00 UTC",
|
||||
new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
|
||||
@ -127,7 +128,7 @@ public class DefaultDateTypeAdapterTest extends TestCase {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
Locale.setDefault(Locale.US);
|
||||
try {
|
||||
String afterYearSep = VersionUtils.isJava9OrLater() ? ", " : " ";
|
||||
String afterYearSep = JavaVersion.isJava9OrLater() ? ", " : " ";
|
||||
assertFormatted(String.format("Dec 31, 1969%s4:00:00 PM", afterYearSep),
|
||||
new DefaultDateTypeAdapter(Date.class));
|
||||
assertParsed("Dec 31, 1969 4:00:00 PM", new DefaultDateTypeAdapter(Date.class));
|
||||
|
@ -27,6 +27,7 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
@ -56,7 +57,6 @@ import java.util.TimeZone;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.util.VersionUtils;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -330,7 +330,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
||||
public void testDefaultDateSerialization() {
|
||||
Date now = new Date(1315806903103L);
|
||||
String json = gson.toJson(now);
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
assertEquals("\"Sep 11, 2011, 10:55:03 PM\"", json);
|
||||
} else {
|
||||
assertEquals("\"Sep 11, 2011 10:55:03 PM\"", json);
|
||||
@ -375,7 +375,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
||||
public void testDefaultJavaSqlTimestampSerialization() {
|
||||
Timestamp now = new java.sql.Timestamp(1259875082000L);
|
||||
String json = gson.toJson(now);
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
assertEquals("\"Dec 3, 2009, 1:18:02 PM\"", json);
|
||||
} else {
|
||||
assertEquals("\"Dec 3, 2009 1:18:02 PM\"", json);
|
||||
@ -405,7 +405,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
Date now = new Date(1315806903103L);
|
||||
String json = gson.toJson(now);
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
assertEquals("\"Sep 11, 2011, 10:55:03 PM\"", json);
|
||||
} else {
|
||||
assertEquals("\"Sep 11, 2011 10:55:03 PM\"", json);
|
||||
|
@ -33,6 +33,7 @@ import com.google.gson.common.TestTypes.ClassWithObjects;
|
||||
import com.google.gson.common.TestTypes.ClassWithTransientFields;
|
||||
import com.google.gson.common.TestTypes.Nested;
|
||||
import com.google.gson.common.TestTypes.PrimitiveArray;
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
@ -44,7 +45,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import com.google.gson.util.VersionUtils;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -484,7 +484,7 @@ public class ObjectTest extends TestCase {
|
||||
public void testDateAsMapObjectField() {
|
||||
HasObjectMap a = new HasObjectMap();
|
||||
a.map.put("date", new Date(0));
|
||||
if (VersionUtils.isJava9OrLater()) {
|
||||
if (JavaVersion.isJava9OrLater()) {
|
||||
assertEquals("{\"map\":{\"date\":\"Dec 31, 1969, 4:00:00 PM\"}}", gson.toJson(a));
|
||||
} else {
|
||||
assertEquals("{\"map\":{\"date\":\"Dec 31, 1969 4:00:00 PM\"}}", gson.toJson(a));
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Gson authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.gson.internal;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.gson.internal.JavaVersion;
|
||||
|
||||
/**
|
||||
* Unit and functional tests for {@link JavaVersion}
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
*/
|
||||
public class JavaVersionTest {
|
||||
// Borrowed some of test strings from https://github.com/prestodb/presto/blob/master/presto-main/src/test/java/com/facebook/presto/server/TestJavaVersion.java
|
||||
|
||||
@Test
|
||||
public void testGetMajorJavaVersion() {
|
||||
JavaVersion.getMajorJavaVersion();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJava6() {
|
||||
assertEquals(6, JavaVersion.getMajorJavaVersion("1.6.0")); // http://www.oracle.com/technetwork/java/javase/version-6-141920.html
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJava7() {
|
||||
assertEquals(7, JavaVersion.getMajorJavaVersion("1.7.0")); // http://www.oracle.com/technetwork/java/javase/jdk7-naming-418744.html
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJava8() {
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8"));
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0"));
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0_131"));
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0_60-ea"));
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0_111-internal"));
|
||||
|
||||
// openjdk8 per https://github.com/AdoptOpenJDK/openjdk-build/issues/93
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0-internal"));
|
||||
assertEquals(8, JavaVersion.getMajorJavaVersion("1.8.0_131-adoptopenjdk"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJava9() {
|
||||
// Legacy style
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9.0.4")); // Oracle JDK 9
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9-Debian")); // Debian as reported in https://github.com/google/gson/issues/1310
|
||||
// New style
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9-ea+19"));
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9+100"));
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9.0.1+20"));
|
||||
assertEquals(9, JavaVersion.getMajorJavaVersion("9.1.1+20"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJava10() {
|
||||
assertEquals(10, JavaVersion.getMajorJavaVersion("10.0.1")); // Oracle JDK 10.0.1
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownVersionFormat() {
|
||||
assertEquals(6, JavaVersion.getMajorJavaVersion("Java9")); // unknown format
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user