Bug 525854 - Fix Java SE platform detection and clean up platform code
Signed-off-by: Tomas Kraus <tomas.kraus@oracle.com>
Reviewed-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/framework/ReflectionHelper.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/framework/ReflectionHelper.java
index 1a17232..4d1c9c4 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/framework/ReflectionHelper.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/framework/ReflectionHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2016 Oracle and/or its affiliates.
+ * Copyright (c) 2015, 2017 Oracle and/or its affiliates.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -145,6 +145,25 @@ public static final Object invokeMethod(
}
/**
+ * Invoke a method of the specified class instance.
+ * @param name Method name.
+ * @param obj Class instance containing method to invoke.
+ * @param parameterTypes Method parameter array.
+ * @param returnType Class to be returned.
+ * @param args An array of objects to be passed as arguments to the method call
+ * @throws InvocationTargetException If the underlying constructor throws an exception.
+ * @throws IllegalArgumentException If an unwrapping conversion fails.
+ * @throws IllegalAccessException If the underlying field is either inaccessible or final.
+ * @throws SecurityException If a security manager is present and access to the field was denied.
+ * @throws NoSuchMethodException If a field with the specified name is not found.
+ */
+ public static final <T> T invokeMethod(
+ final String name, final Object obj, final Class<?>[] parameterTypes, final Class<T> returnType, final Object... args)
+ throws ReflectiveOperationException {
+ return returnType.cast(invokeMethod(name, obj, parameterTypes, args));
+ }
+
+ /**
* Invoke static method of the specified class.
* @param name Method name.
* @param c Class containing method to invoke.
@@ -171,4 +190,23 @@ public static final Object invokeStaticMethod(
return result;
}
+ /**
+ * Invoke static method of the specified class.
+ * @param name Method name.
+ * @param c Class containing method to invoke.
+ * @param parameterTypes Method parameter array.
+ * @param returnType Class to be returned.
+ * @param args An array of objects to be passed as arguments to the method call
+ * @throws InvocationTargetException If the underlying constructor throws an exception.
+ * @throws IllegalArgumentException If an unwrapping conversion fails.
+ * @throws IllegalAccessException If the underlying field is either inaccessible or final.
+ * @throws SecurityException If a security manager is present and access to the field was denied.
+ * @throws NoSuchMethodException If a field with the specified name is not found.
+ */
+ public static final <T> T invokeStaticMethod(
+ final String name, final Class c, final Class<?>[] parameterTypes, final Class<T> returnType, final Object... args)
+ throws ReflectiveOperationException {
+ return returnType.cast(invokeStaticMethod(name, c, parameterTypes, args));
+ }
+
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/HelperTestModel.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/HelperTestModel.java
index 749c894..0df39e3 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/HelperTestModel.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/HelperTestModel.java
@@ -31,6 +31,7 @@ public static TestSuite getDataTypeComparisonTestSuite() {
suite.setDescription("This suite tests common helper methods and methods which compare data types");
suite.addTestSuite(org.eclipse.persistence.testing.tests.helper.JavaUtilTest.class);
+ suite.addTestSuite(org.eclipse.persistence.testing.tests.helper.JavaVersionTest.class);
suite.addTest(new CompareArrayContentTest());
suite.addTest(new CompareArrayLengthTest());
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaUtilTest.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaUtilTest.java
index c513c3d..035c3fd 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaUtilTest.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaUtilTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -14,6 +14,7 @@
import org.eclipse.persistence.internal.helper.JavaSEPlatform;
import org.eclipse.persistence.internal.helper.JavaVersion;
+import org.eclipse.persistence.testing.framework.ReflectionHelper;
import org.junit.Test;
/**
@@ -22,6 +23,51 @@
*/
public class JavaUtilTest extends junit.framework.TestCase {
+ // Valid version number pairs.
+ static final int[][] VALID = {
+ {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9},
+ {9, 0}, {10, 0}, {18, 3}, {18, 9}
+ };
+
+ // Invalid version number pairs.
+ static final int[][] INVALID = {
+ {0, 0}, {0, 1}, {0, 3}, {0, 5}, {0, 7}, {0, 9},
+ {1, 0}, {2, 0}, {2, 1}, {2, 2}, {3, 0}, {4, 0}, {1, 10},
+ {18, 1}, {18, 2}, {18, 4}, {18, 5}, {18, 6}, {18, 7}, {18, 8}, {18, 10}, {18, 11}, {18, 12}
+ };
+
+ // DEFAULT platform value.
+ static final JavaSEPlatform LATEST = initDefault();
+
+ /** Version numbers result mapping. Covers exceptions.
+ * See also {@code JavaSEPlatform.stringValuesMap} initialization code
+ * and {@link JavaSEPlatform#toValue(int, int)}.
+ * 1.9 -> 9.0
+ * @param version source version numbers
+ * @return result version numbers
+ */
+ static int[] resultMapping(int[] version) {
+ switch (version[0]) {
+ case 1:
+ switch (version[1]) {
+ case 9: return new int[] {9, 0};
+ default: return version;
+ }
+ default: return version;
+ }
+ }
+
+ /**
+ * Initialize value of JavaSEPlatform.DEFAULT.
+ * @return value of JavaSEPlatform.DEFAULT.
+ */
+ private static final JavaSEPlatform initDefault() {
+ try {
+ return ReflectionHelper.getPrivateStatic(JavaSEPlatform.class, "LATEST");
+ } catch (ReflectiveOperationException e) {
+ return null;
+ }
+ }
/**
* Constructs an instance of Java utilities.
* @param name java.lang.String
@@ -62,31 +108,28 @@ public void testJavaVersion() {
*/
@Test
public void testStringToPlatform() {
- // Valid version number pairs.
- int[][] valid = {{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7},
- {1, 8}, {1, 9}, {9, 0}};
- int[][] invalid = {{0, 0}, {0, 1}, {0, 3}, {0, 5}, {0, 7}, {0, 9},
- {1, 0}, {2, 0}, {2, 1}, {2, 2}, {3, 0}, {4, 0}, {1, 10}};
// Verify valid pairs.
- for (int [] version : valid) {
+ for (int [] version : VALID) {
int major = version[0];
int minor = version[1];
String versionString = JavaSEPlatform.versionString(major, minor);
JavaSEPlatform platform = JavaSEPlatform.toValue(versionString);
assertNotNull("There should exist platform for valid platform"
- +" version numbers.", platform);
+ +" version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", platform);
+ int[] result = resultMapping(version);
assertTrue("Returned platform version numbers do not match provided"
- + " version numbers", major == platform.getMajor()
- && minor == platform.getMinor());
+ + " version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]",
+ result[0] == platform.getMajor() && result[1] == platform.getMinor());
}
// Invalid version number pairs.
- for (int [] version : invalid) {
+ for (int [] version : INVALID) {
int major = version[0];
int minor = version[1];
String versionString = JavaSEPlatform.versionString(major, minor);
JavaSEPlatform platform = JavaSEPlatform.toValue(major, minor);
- assertNull("Returned platform shall be null for invalid version "
- + "number", platform);
+ assertTrue("Returned platform shall be JavaSEPlatform.DEFAULT for invalid version "
+ + "number ["+Integer.toString(major)+","+Integer.toString(minor)+"]",
+ LATEST.getMajor() == platform.getMajor() && LATEST.getMinor() == platform.getMinor());
}
}
@@ -96,29 +139,26 @@ public void testStringToPlatform() {
*/
@Test
public void testMajorMinorToPlatform() {
- // Valid version number pairs.
- int[][] valid = {{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7},
- {1, 8}, {1, 9}, {9, 0}};
- int[][] invalid = {{0, 0}, {0, 1}, {0, 3}, {0, 5}, {0, 7}, {0, 9},
- {1, 0}, {2, 0}, {2, 1}, {2, 2}, {3, 0}, {4, 0}, {1, 10}};
// Verify valid pairs.
- for (int [] version : valid) {
+ for (int [] version : VALID) {
int major = version[0];
int minor = version[1];
JavaSEPlatform platform = JavaSEPlatform.toValue(major, minor);
assertNotNull("There should exist platform for valid platform"
- +" version numbers.", platform);
+ +" version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", platform);
+ int[] result = resultMapping(version);
assertTrue("Returned platform version numbers do not match provided"
- + " version numbers", major == platform.getMajor()
- && minor == platform.getMinor());
+ + " version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]",
+ result[0] == platform.getMajor() && result[1] == platform.getMinor());
}
// Invalid version number pairs.
- for (int [] version : invalid) {
+ for (int [] version : INVALID) {
int major = version[0];
int minor = version[1];
JavaSEPlatform platform = JavaSEPlatform.toValue(major, minor);
- assertNull("Returned platform shall be null for invalid version "
- + "number", platform);
+ assertTrue("Returned platform shall be JavaSEPlatform.DEFAULT for invalid version "
+ + "number ["+Integer.toString(major)+","+Integer.toString(minor)+"]",
+ LATEST.getMajor() == platform.getMajor() && LATEST.getMinor() == platform.getMinor());
}
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaVersionTest.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaVersionTest.java
new file mode 100644
index 0000000..3625beb
--- /dev/null
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/helper/JavaVersionTest.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Tomas Kraus - 2017/10/11
+ * Bug 525854 - Fix Java SE platform detection and clean up platform code
+ ******************************************************************************/
+package org.eclipse.persistence.testing.tests.helper;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.persistence.internal.helper.JavaSEPlatform;
+import org.eclipse.persistence.internal.helper.JavaVersion;
+import org.eclipse.persistence.testing.framework.ReflectionHelper;
+import org.junit.Test;
+
+import junit.framework.TestCase;
+
+public class JavaVersionTest extends TestCase {
+
+ /**
+ * Check whether current Java has {@code Runtime.Version} class.
+ * @return Value of {@code true} when current Java has {@code Runtime.Version} class or {@code false} otherwise.
+ */
+ private static boolean hasRuntimeVersion() {
+ final Method[] methods = Runtime.class.getDeclaredMethods();
+ for (final Method method : methods) {
+ if ("version".equals(method.getName()) && method.getParameterCount() == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test Java version retrieval from {@code Runtime.Version}. It just calls {@code JavaVersion#runtimeVersion()} method
+ * on current Java SE when >9 and checks that no exception is thrown.
+ */
+ @Test
+ public void testRuntimeVersion() {
+ if (!hasRuntimeVersion()) {
+ return;
+ }
+ try {
+ final JavaVersion version = ReflectionHelper.<JavaVersion>invokeStaticMethod("runtimeVersion", JavaVersion.class, null, JavaVersion.class);
+ assertTrue("Minimal Java 9 required", version.getMajor() >= 9);
+ } catch (ReflectiveOperationException e) {
+ fail("Exception: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Test Java version retrieval from {@code java.specification.version} system property. It just calls
+ * {@code JavaVersion#propertyVersionParser(String)} method with current Java SE {@code java.specification.version}
+ * system property value and checks that no exception is thrown.
+ */
+ @Test
+ public void testPropertyVersion() {
+ try {
+ final String versionString = ReflectionHelper.<String>invokeStaticMethod(
+ "vmVersionString", JavaVersion.class, null, String.class);
+ final JavaVersion version = ReflectionHelper.<JavaVersion>invokeStaticMethod(
+ "propertyVersionParser", JavaVersion.class, new Class[] {String.class}, JavaVersion.class, versionString);
+ } catch (ReflectiveOperationException e) {
+ fail("Exception: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Verify Java version parser on set of valid and invalid {@code java.specification.version} system property values.
+ * Because all version strings are in {@code [0-9]+'.'[0-9]+} format, parser shall always return {@code JavaVersion}
+ * instance containing provided version numbers.
+ */
+ @Test
+ public void testPropertyVersionParser() {
+ // Verify valid pairs.
+ for (final int [] version : JavaUtilTest.VALID) {
+ final int major = version[0];
+ final int minor = version[1];
+ final String versionString = JavaSEPlatform.versionString(major, minor);
+ try {
+ final JavaVersion javaVersion = ReflectionHelper.<JavaVersion>invokeStaticMethod(
+ "propertyVersionParser", JavaVersion.class, new Class[] {String.class}, JavaVersion.class, versionString);
+ assertNotNull("JavaVersion instance must be returned for valid platform"
+ +" version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", javaVersion);
+ assertTrue("Returned JavaVersion instance numbers do not match provided"
+ + " version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", major == javaVersion.getMajor()
+ && minor == javaVersion.getMinor());
+ } catch (ReflectiveOperationException e) {
+ fail("Exception: " + e.getMessage());
+ }
+ }
+ // Verify invalid pairs.
+ for (final int [] version : JavaUtilTest.INVALID) {
+ final int major = version[0];
+ final int minor = version[1];
+ final String versionString = JavaSEPlatform.versionString(major, minor);
+ try {
+ final JavaVersion javaVersion = ReflectionHelper.<JavaVersion>invokeStaticMethod(
+ "propertyVersionParser", JavaVersion.class, new Class[] {String.class}, JavaVersion.class, versionString);
+ assertNotNull("JavaVersion instance must be returned for invalid platform"
+ +" version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", javaVersion);
+ assertTrue("Returned JavaVersion instance numbers do not match provided"
+ + " version number ["+Integer.toString(major)+","+Integer.toString(minor)+"]", major == javaVersion.getMajor()
+ && minor == javaVersion.getMinor());
+ } catch (ReflectiveOperationException e) {
+ fail("Exception: " + e.getMessage());
+ }
+ }
+ }
+
+}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/Version.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/Version.java
index 9c4b6bb..4339695 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/Version.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/Version.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -15,8 +15,6 @@
******************************************************************************/
package org.eclipse.persistence;
-import org.eclipse.persistence.internal.helper.JavaSEPlatform;
-
/**
* This class stores variables for the version and build numbers that are used
* in printouts and exceptions.
@@ -44,40 +42,13 @@ public class Version {
/** Version numbers separator. */
private static final char SEPARATOR = '.';
- // This is replaced by JavaSEPlatform. It's here just because of backward compatibility.
- /**
- * Keep track of JDK version in order to make some decisions about data structures.
- * @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7.
- */
- @Deprecated
- public static final int JDK_VERSION_NOT_SET = 0;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static final int JDK_1_5 = 1;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static final int JDK_1_6 = 2;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static final int JDK_1_7 = 3;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static final int JDK_1_8 = 4;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static final int JDK_1_9 = 5;
- /** @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7. */
- @Deprecated
- public static int JDK_VERSION = JDK_VERSION_NOT_SET;
-
/**
* Returns version {@link String} containing three part version number
* and build qualifier.
* @return Version {@link String}.
*/
- public static String getVersionString ( ) {
- StringBuilder sb = new StringBuilder(
- version.length() + 1 + qualifier.length());
+ public static String getVersionString() {
+ StringBuilder sb = new StringBuilder(version.length() + 1 + qualifier.length());
sb.append(version);
sb.append(SEPARATOR);
sb.append(qualifier);
@@ -120,127 +91,17 @@ public static String getBuildType() {
return buildType;
}
- /**
- * INTERNAL:
- * Return the JDK version we are using.
- * @deprecated Use {@code JavaSEPlatform.CURRENT} instead.
- * Will be removed in 2.7.
- */
- @Deprecated
- public static int getJDKVersion() {
- switch(JavaSEPlatform.CURRENT) {
- case v1_7:
- JDK_VERSION = JDK_1_7;
- break;
- case v1_8:
- JDK_VERSION = JDK_1_8;
- break;
- case v1_9:
- case v9_0:
- JDK_VERSION = JDK_1_9;
- break;
- default:
- throw new IllegalStateException("Running on unsupported Java SE: "
- + JavaSEPlatform.CURRENT.toString());
- }
- return JDK_VERSION;
+ public static void printVersion() {
+ System.out.println(getVersionString());
}
- /**
- * Set 1.5 as current Java SE version.
- * @throws UnsupportedOperationException when invoked because Java SE 1.5
- * is not supported by current EclipseLink.
- * @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7.
- */
- @Deprecated
- public static void useJDK15() {
- throw new UnsupportedOperationException(
- "Java SE 1.5 is not supported by current EclipseLink.");
- }
-
- /**
- * Set 1.6 as current Java SE version.
- * @throws UnsupportedOperationException when invoked because Java SE 1.6
- * is not supported by current EclipseLink.
- * @deprecated Use {@link JavaSEPlatform} instead. Will be removed in 2.7.
- */
- @Deprecated
- public static void useJDK16() {
- throw new UnsupportedOperationException(
- "Java SE 1.6 is not supported by current EclipseLink.");
- }
-
- // Public API wrapper, use JavaSEPlatform.is(JavaSEPlatform.v1_5)
- // internally.
- /**
- * Check whether we are running on Java SE 1.5.
- * This will always return {@code false} because Java SE 1.5 is not
- * supported by current EclipseLink.
- * @return Value of {@code true} when we do and value of {@code false}
- * when we do not run on Java SE 1.5.
- */
- public static boolean isJDK15() {
- return JavaSEPlatform.is(JavaSEPlatform.v1_5);
- }
-
- // Public API wrapper, use JavaSEPlatform.is(JavaSEPlatform.v1_6)
- // internally.
- /**
- * Check whether we are running on Java SE 1.6.
- * This will always return {@code false} because Java SE 1.6 is not
- * supported by current EclipseLink.
- * @return Value of {@code true} when we do and value of {@code false}
- * when we do not run on Java SE 1.6.
- */
- public static boolean isJDK16() {
- return JavaSEPlatform.is(JavaSEPlatform.v1_6);
- }
-
- // Public API wrapper, use JavaSEPlatform.is(JavaSEPlatform.v1_7)
- // internally.
- /**
- * Check whether we are running on Java SE 1.7.
- * @return Value of {@code true} when we do and value of {@code false}
- * when we do not run on Java SE 1.7.
- */
- public static boolean isJDK17() {
- return JavaSEPlatform.is(JavaSEPlatform.v1_7);
- }
-
- // Public API wrapper, use JavaSEPlatform.is(JavaSEPlatform.v1_8)
- // internally.
- /**
- * Check whether we are running on Java SE 1.8.
- * @return Value of {@code true} when we do and value of {@code false}
- * when we do not run on Java SE 1.8.
- */
- public static boolean isJDK18() {
- return JavaSEPlatform.is(JavaSEPlatform.v1_8);
- }
-
- // Public API wrapper, use JavaSEPlatform.is(JavaSEPlatform.v1_9)
- // internally.
- /**
- * Check whether we are running on Java SE 1.9.
- * @return Value of {@code true} when we do and value of {@code false}
- * when we do not run on Java SE 1.9.
- */
- public static boolean isJDK19() {
- return JavaSEPlatform.is(JavaSEPlatform.v9_0) || JavaSEPlatform.is(JavaSEPlatform.v1_9);
- }
-
- public static void printVersion ( ) {
- System.out.println( getVersionString() );
- }
-
- public static void main ( String[] args ) {
- System.out.println(
- "\n" + getProduct() + " (EclipseLink)"
- + "\n Build Version: " + getVersionString()
- + "\n Build Qualifier: " + getQualifier()
- + "\n Build Date: " + getBuildDate()
- + "\n Build Time: " + getBuildTime()
- + "\n SVN Revision: " + getBuildRevision()
- );
+ public static void main(String[] args) {
+ System.out.println();
+ System.out.print(getProduct()); System.out.println(" (EclipseLink)");
+ System.out.print(" Build Version: "); System.out.println(getVersionString());
+ System.out.print(" Build Qualifier: "); System.out.println(getQualifier());
+ System.out.print(" Build Date: "); System.out.println(getBuildDate());
+ System.out.print(" Build Time: "); System.out.println(getBuildTime());
+ System.out.print(" Build Revision: "); System.out.println(getBuildRevision());
}
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK15Platform.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK15Platform.java
deleted file mode 100644
index 5f468c2..0000000
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK15Platform.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- * Oracle - initial API and implementation from Oracle TopLink
- ******************************************************************************/
-package org.eclipse.persistence.internal.helper;
-
-import java.sql.SQLException;
-import java.util.regex.Pattern;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * INTERNAL:
- * Implements operations specific to JDK 1.5
- */
-public class JDK15Platform implements JDKPlatform {
-
- /**
- * PERF: The like expression compiled Pattern objects are cached
- * to avoid re-compilation on every usage.
- */
- protected static final ConcurrentHashMap patternCache = new ConcurrentHashMap();
-
- /**
- * PERF: The regular expression compiled Pattern objects are cached
- * to avoid re-compilation on every usage.
- */
- protected static final ConcurrentHashMap regexpPatternCache = new ConcurrentHashMap();
-
- /**
- * INTERNAL:
- * An implementation of in memory queries with Like which uses the
- * regular expression framework.
- */
- public Boolean conformLike(Object left, Object right) {
- if ((left == null) && (right == null)) {
- return Boolean.TRUE;
- } else if ((left == null) || (right == null)) {
- return Boolean.FALSE;
- }
- left = String.valueOf(left);
- right = String.valueOf(right);
- // PERF: First check the pattern cache for the pattern.
- // Note that the original string is the key, to avoid having to translate it first.
- Pattern pattern = (Pattern)patternCache.get(right);
- if (pattern == null) {
- // Bug 3936427 - Replace regular expression reserved characters with escaped version of those characters
- // For instance replace ? with \?
- String convertedRight = Helper.convertLikeToRegex((String)right);
-
- pattern = Pattern.compile(convertedRight);
- // Ensure cache does not grow beyond 100.
- if (patternCache.size() > 100) {
- patternCache.remove(patternCache.keySet().iterator().next());
- }
- patternCache.put(right, pattern);
- }
- boolean match = pattern.matcher((String)left).matches();
- if (match) {
- return Boolean.TRUE;
- } else {
- return Boolean.FALSE;
- }
- }
-
- /**
- * INTERNAL:
- * An implementation of in memory queries with Regexp which uses the
- * regular expression framework.
- */
- public Boolean conformRegexp(Object left, Object right) {
- if ((left == null) && (right == null)) {
- return Boolean.TRUE;
- } else if ((left == null) || (right == null)) {
- return Boolean.FALSE;
- }
- left = String.valueOf(left);
- right = String.valueOf(right);
- // PERF: First check the pattern cache for the pattern.
- // Note that the original string is the key, to avoid having to translate it first.
- Pattern pattern = (Pattern)regexpPatternCache.get(right);
- if (pattern == null) {
- pattern = Pattern.compile((String)right);
- // Ensure cache does not grow beyond 100.
- if (regexpPatternCache.size() > 100) {
- regexpPatternCache.remove(regexpPatternCache.keySet().iterator().next());
- }
- regexpPatternCache.put(right, pattern);
- }
- boolean match = pattern.matcher((String)left).matches();
- if (match) {
- return Boolean.TRUE;
- } else {
- return Boolean.FALSE;
- }
- }
-
- /**
- * Indicates whether the passed object implements java.sql.SQLXML introduced in jdk 1.6
- */
- public boolean isSQLXML(Object object) {
- return false;
- }
-
- /**
- * Casts the passed object to SQLXML and calls getString and free methods
- */
- public String getStringAndFreeSQLXML(Object sqlXml) throws SQLException {
- return null;
- }
-}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK16Platform.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK16Platform.java
deleted file mode 100644
index 813c36b..0000000
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDK16Platform.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- * ailitchev - 2010/08/19
- * Bug 322960 - TWO TESTS IN CUSTOMFEATURESJUNITTESTSUITE FAILED WITH 11.2.0.2 DRIVER
- ******************************************************************************/
-package org.eclipse.persistence.internal.helper;
-
-import java.sql.SQLException;
-import java.sql.SQLXML;
-
-/**
- * INTERNAL:
- * Implements operations specific to JDK 1.6
- */
-public class JDK16Platform extends JDK15Platform {
-
- /**
- * Indicates whether the passed object implements java.sql.SQLXML introduced in jdk 1.6
- */
- public boolean isSQLXML(Object object) {
- return (object instanceof SQLXML);
- }
-
- /**
- * Casts the passed object to SQLXML and calls getString and free methods
- */
- public String getStringAndFreeSQLXML(Object sqlXml) throws SQLException {
- String str = ((SQLXML)sqlXml).getString();
- ((SQLXML)sqlXml).free();
- return str;
- }
-}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDKPlatform.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDKPlatform.java
deleted file mode 100644
index 7b7ded6..0000000
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JDKPlatform.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- * Oracle - initial API and implementation from Oracle TopLink
- ******************************************************************************/
-package org.eclipse.persistence.internal.helper;
-
-import java.sql.SQLException;
-
-/**
- * INTERNAL:
- * Interface which abstracts the version of the JDK we are on.
- * This should only implement methods that are dependent on JDK version
- * The implementers should implement the minimum amount of functionality required to
- * allow support of multiple versions of the JDK.
- * @see JDK15Platform
- * @see JavaPlatform
- * @author Tom Ware
- */
-public interface JDKPlatform {
-
- /**
- * Conforming queries with LIKE will act differently in different JDKs.
- */
- Boolean conformLike(Object left, Object right);
-
- /**
- * Conforming queries with REGEXP will act differently in different JDKs.
- */
- Boolean conformRegexp(Object left, Object right);
-
- /**
- * Indicates whether the passed object implements java.sql.SQLXML introduced in jdk 1.6
- */
- boolean isSQLXML(Object object);
-
- /**
- * Casts the passed object to SQLXML and calls getString and free methods
- */
- String getStringAndFreeSQLXML(Object sqlXml) throws SQLException;
-}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaPlatform.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaPlatform.java
index 9e2eb13..9cf4f9a 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaPlatform.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaPlatform.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,16 +9,17 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * ailitchev - 2010/08/19
+ * Bug 322960 - TWO TESTS IN CUSTOMFEATURESJUNITTESTSUITE FAILED WITH 11.2.0.2 DRIVER
+ * Tomas Kraus - 2017/10/11
+ * Bug 525854 - Fix Java SE platform detection and clean up platform code
******************************************************************************/
package org.eclipse.persistence.internal.helper;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
import java.sql.SQLException;
-
-import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
-import org.eclipse.persistence.internal.security.PrivilegedClassForName;
-import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
+import java.sql.SQLXML;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
/**
* INTERNAL:
@@ -29,61 +30,75 @@
* @author Tom Ware
*/
public class JavaPlatform {
- protected static JDKPlatform platform = null;
/**
- * INTERNAL:
- * Get the version of JDK being used from the Version class.
- * @return JDKPlatform a platform appropriate for the version of JDK being used.
+ * PERF: The like expression compiled Pattern objects are cached
+ * to avoid re-compilation on every usage.
*/
- protected static JDKPlatform getPlatform() {
- if (platform == null) {
- if (JavaSEPlatform.CURRENT.atLeast(JavaSEPlatform.v1_6)) {
- try {
- Class platformClass = null;
- // use class.forName() to avoid loading the JDK 1.6 class unless it is needed.
- if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
- try {
- platformClass = AccessController.doPrivileged(new PrivilegedClassForName("org.eclipse.persistence.internal.helper.JDK16Platform"));
- } catch (PrivilegedActionException exception) {
- }
- } else {
- platformClass = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName("org.eclipse.persistence.internal.helper.JDK16Platform");
- }
- if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
- try {
- platform = (JDKPlatform)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(platformClass));
- } catch (PrivilegedActionException exception) {
- }
- } else {
- platform = (JDKPlatform)PrivilegedAccessHelper.newInstanceFromClass(platformClass);
- }
- } catch (Exception exception) {
- }
- }
- if (platform == null) {
- platform = new JDK15Platform();
- }
- }
- return platform;
- }
+ private static final ConcurrentHashMap patternCache = new ConcurrentHashMap();
/**
- * INTERNAL:
- * Conform an expression which uses the operator "like" for an in-memory query
- * @return Boolean (TRUE, FALSE, null == unknown)
+ * PERF: The regular expression compiled Pattern objects are cached
+ * to avoid re-compilation on every usage.
+ */
+ private static final ConcurrentHashMap regexpPatternCache = new ConcurrentHashMap();
+
+ /**
+ * INTERNAL:
+ * An implementation of in memory queries with Like which uses the
+ * regular expression framework.
*/
public static Boolean conformLike(Object left, Object right) {
- return getPlatform().conformLike(left, right);
+ if ((left == null) && (right == null)) {
+ return Boolean.TRUE;
+ } else if ((left == null) || (right == null)) {
+ return Boolean.FALSE;
+ }
+ left = String.valueOf(left);
+ right = String.valueOf(right);
+ // PERF: First check the pattern cache for the pattern.
+ // Note that the original string is the key, to avoid having to translate it first.
+ Pattern pattern = (Pattern)patternCache.get(right);
+ if (pattern == null) {
+ // Bug 3936427 - Replace regular expression reserved characters with escaped version of those characters
+ // For instance replace ? with \?
+ String convertedRight = Helper.convertLikeToRegex((String)right);
+
+ pattern = Pattern.compile(convertedRight);
+ // Ensure cache does not grow beyond 100.
+ if (patternCache.size() > 100) {
+ patternCache.remove(patternCache.keySet().iterator().next());
+ }
+ patternCache.put(right, pattern);
+ }
+ return pattern.matcher((String)left).matches();
}
/**
- * INTERNAL:
- * Conform an expression which uses the operator "regexp" for an in-memory query
- * @return Boolean (TRUE, FALSE, null == unknown)
+ * INTERNAL:
+ * An implementation of in memory queries with Regexp which uses the
+ * regular expression framework.
*/
public static Boolean conformRegexp(Object left, Object right) {
- return getPlatform().conformRegexp(left, right);
+ if ((left == null) && (right == null)) {
+ return Boolean.TRUE;
+ } else if ((left == null) || (right == null)) {
+ return Boolean.FALSE;
+ }
+ left = String.valueOf(left);
+ right = String.valueOf(right);
+ // PERF: First check the pattern cache for the pattern.
+ // Note that the original string is the key, to avoid having to translate it first.
+ Pattern pattern = (Pattern)regexpPatternCache.get(right);
+ if (pattern == null) {
+ pattern = Pattern.compile((String)right);
+ // Ensure cache does not grow beyond 100.
+ if (regexpPatternCache.size() > 100) {
+ regexpPatternCache.remove(regexpPatternCache.keySet().iterator().next());
+ }
+ regexpPatternCache.put(right, pattern);
+ }
+ return pattern.matcher((String)left).matches();
}
/**
@@ -91,7 +106,7 @@ public static Boolean conformRegexp(Object left, Object right) {
* Indicates whether the passed object implements java.sql.SQLXML introduced in jdk 1.6
*/
public static boolean isSQLXML(Object object) {
- return getPlatform().isSQLXML(object);
+ return (object instanceof SQLXML);
}
/**
@@ -99,6 +114,9 @@ public static boolean isSQLXML(Object object) {
* Casts the passed object to SQLXML and calls getString and free methods
*/
public static String getStringAndFreeSQLXML(Object sqlXml) throws SQLException {
- return getPlatform().getStringAndFreeSQLXML(sqlXml);
+ String str = ((SQLXML)sqlXml).getString();
+ ((SQLXML)sqlXml).free();
+ return str;
}
+
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaSEPlatform.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaSEPlatform.java
index 0eb5ab5..0f69ca6 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaSEPlatform.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaSEPlatform.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -37,10 +37,67 @@ public enum JavaSEPlatform implements Comparable<JavaSEPlatform> {
v1_7(1,7),
/** Java SE 1.8. */
v1_8(1,8),
- /** Java SE 9. */
- v1_9(1,9),
- /** Java SE 9. */
- v9_0(9, 0);
+ /** Java SE 9. Version alias 1.9 is added too.*/
+ v9_0(9,0, new Version(1,9)),
+ /** Java SE 10. */
+ v10_0(10,0),
+ /** Java SE 18.3. */
+ v18_3(18,3),
+ /** Java SE 18.9. */
+ v18_9(18,9);
+
+ public static final class Version {
+ /**
+ * Creates an instance of Java SE version numbers.
+ * @param major major version number
+ * @param minor minor version number
+ */
+ private Version(final int major, final int minor) {
+ this.major = major;
+ this.minor = minor;
+ }
+
+ /** Major version number. */
+ private final int major;
+
+ /** Minor version number. */
+ private final int minor;
+
+ /**
+ * Get major version number.
+ * @return Major version number.
+ */
+ public final int getMajor() {
+ return major;
+ }
+
+ /**
+ * Get minor version number.
+ * @return Minor version number.
+ */
+ public final int getMinor() {
+ return minor;
+ }
+
+ /**
+ * Return computer readable {@code String} containing version numbers in {@code <major> '.' <minor>} format.
+ * @return computer readable {@code String} containing version numbers
+ */
+ public String versionString() {
+ return JavaSEPlatform.versionString(major, minor);
+ }
+
+ // Currently this is identical with versionString() method.
+ /**
+ * Return version as human readable {@code String}.
+ * @return version as human readable {@code String}.
+ */
+ @Override
+ public String toString() {
+ return JavaSEPlatform.versionString(major, minor);
+ }
+
+ }
/**
* Stored <code>String</code> values for backward <code>String</code>
@@ -52,7 +109,15 @@ public enum JavaSEPlatform implements Comparable<JavaSEPlatform> {
// Initialize backward String conversion Map.
static {
for (JavaSEPlatform platform : JavaSEPlatform.values()) {
+ // Primary version numbers mapping.
stringValuesMap.put(platform.versionString(), platform);
+ // Additional version numbers mapping.
+ Version[] additional = platform.getAdditionalVersions();
+ if (additional != null) {
+ for (Version version : additional) {
+ stringValuesMap.put(version.versionString(), platform);
+ }
+ }
}
}
@@ -63,8 +128,11 @@ public enum JavaSEPlatform implements Comparable<JavaSEPlatform> {
public static final JavaSEPlatform CURRENT
= JavaVersion.vmVersion().toPlatform();
- /** Lowest supported Java SE platform. Currently it's Java SE 1.7. */
- public static final JavaSEPlatform MIN_SUPPORTED = v1_7;
+ /** Lowest supported Java SE platform. Currently it's Java SE 1.8. */
+ public static final JavaSEPlatform MIN_SUPPORTED = v1_8;
+
+ /** Latest Java SE platform. This value is used when Java SE platform detection fails. */
+ static final JavaSEPlatform LATEST = JavaSEPlatform.v18_9;
/**
* Check whether current Java SE is exactly matching provided platform.
@@ -75,6 +143,14 @@ public static boolean is(JavaSEPlatform platform) {
}
/**
+ * Check whether current Java SE is at least (greater or equal) provided platform.
+ * @param platform Java SE platform to compare with.
+ */
+ public static boolean atLeast(JavaSEPlatform platform) {
+ return CURRENT.atLeast(platform);
+ }
+
+ /**
* Returns a <code>JavaSEPlatform</code> with a value represented by the
* specified <code>String</code>. The <code>JavaSEPlatform</code> returned
* represents existing value only if specified <code>String</code>
@@ -96,14 +172,16 @@ public static JavaSEPlatform toValue(final String platformName) {
}
// There are not too many versions yet so direct mapping in code is simple.
+ // Version 1.9 is considered as valid version for 9.0.
/**
* Returns a <code>JavaSEPlatform</code> matching provided
* <code>major</code> and <code>minor</code> version numbers.
* @param major Major version number.
* @param minor Minor version number.
* @return <code>JavaSEPlatform</code> value matching provided
- * <code>major</code> and <code>minor</code> version numbers
- * or <code>null</code> when such a value does not exist.
+ * <code>major</code> and <code>minor</code> version numbers.
+ * {@code JavaSEPlatform.DEFAULT} value is returned for unknown
+ * Java SE version numbers.
*/
public static JavaSEPlatform toValue(final int major, final int minor) {
switch (major) {
@@ -117,12 +195,20 @@ public static JavaSEPlatform toValue(final int major, final int minor) {
case 6: return v1_6;
case 7: return v1_7;
case 8: return v1_8;
- case 9: return v1_9;
- default: return null;
+ case 9: return v9_0;
+ default: return LATEST;
}
case 9:
return v9_0;
- default: return null;
+ case 10:
+ return v10_0;
+ case 18:
+ switch (minor) {
+ case 3: return v18_3;
+ case 9: return v18_9;
+ default: return LATEST;
+ }
+ default: return LATEST;
}
}
@@ -143,26 +229,27 @@ public static final String versionString(final int major, final int minor) {
/**
* Constructs an instance of Java SE platform.
- * @param major Major version number.
- * @param minor Minor version number.
+ * @param major major version number
+ * @param minor minor version number
+ * @param addVersions additional version numbers if defined
*/
- JavaSEPlatform(final int major, final int minor) {
- this.major = major;
- this.minor = minor;
+ JavaSEPlatform(final int major, final int minor, Version ...addVersions) {
+ this.version = new Version(major, minor);
+ this.addVersions = addVersions;
}
- /** Major version number. */
- private final int major;
+ /** Java SE version numbers. */
+ private final Version version;
- /** Minor version number. */
- private final int minor;
+ /** Additional version numbers. */
+ private final Version[] addVersions;
/**
* Get major version number.
* @return Major version number.
*/
public final int getMajor() {
- return major;
+ return version.major;
}
/**
@@ -170,7 +257,16 @@ public final int getMajor() {
* @return Minor version number.
*/
public final int getMinor() {
- return minor;
+ return version.minor;
+ }
+
+ /**
+ * Get additional version numbers.
+ * @return an array of additional version numbers if exist or {@code null} if no additional
+ * version numbers are defined.
+ */
+ public final Version[] getAdditionalVersions() {
+ return addVersions;
}
/**
@@ -179,7 +275,7 @@ public final int getMinor() {
* @return Value of <code>true</code> if this platform is equal
* or greater to specified platform or <code>false</code> otherwise.
*/
- public boolean atLeast(final JavaSEPlatform platform) {
+ public boolean gte(final JavaSEPlatform platform) {
return compareTo(platform) >= 0;
}
@@ -193,23 +289,21 @@ public boolean isSupported() {
}
/**
- * Generate {@link String} containing minor and major version numbers
- * in {@code <major> '.' <minor>} format.
- * @return Generated {@link String}
+ * Return computer readable {@code String} containing version numbers in {@code <major> '.' <minor>} format.
+ * @return computer readable {@code String} containing version numbers
*/
public String versionString() {
- return versionString(major, minor);
+ return versionString(version.major, version.minor);
}
// Currently this is identical with versionString() method.
/**
- * Convert Java SE platform version value to human readable
- * <code>String</code>.
- * @return A <code>String</code> representation of the value of this object.
+ * Return Java SE platform version as human readable {@code String}.
+ * @return Java SE platform version as human readable {@code String}.
*/
@Override
public String toString() {
- return versionString(major, minor);
+ return versionString(version.major, version.minor);
}
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaVersion.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaVersion.java
index 23ac0cf..c555d67 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaVersion.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/JavaVersion.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -12,10 +12,13 @@
******************************************************************************/
package org.eclipse.persistence.internal.helper;
+import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
+import org.eclipse.persistence.logging.AbstractSessionLog;
+import org.eclipse.persistence.logging.SessionLog;
/**
* Java version storage class. Used for version numbers retrieved from
@@ -35,13 +38,12 @@ public final class JavaVersion {
public static final String VM_VERSION_PROPERTY = "java.specification.version";
/**
- * Java specification version output regular expression pattern.
- * Regular expression contains tokens to read individual version number
- * components. Expected input is string like
- * <code>java version "1.6"</code> or <code>9</code>.
+ * Compiled regular expression pattern to read individual version number components.
+ * Expected input is string like <code>java version "1.6"</code> or <code>9</code>.
*/
- private static final String VM_VERSION_PATTERN =
- "[^0-9]*([0-9]+)(\\.([0-9]+))*";
+ private static final Pattern VM_VERSION_PATTERN = Pattern.compile(
+ "[^0-9]*([0-9]+)(\\.([0-9]+))*"
+ );
/** Number of <code>Matcher</code> groups (REGEX tokens) expected in Java VM
* version output. */
@@ -55,10 +57,72 @@ public static String vmVersionString() {
return PrivilegedAccessHelper.getSystemProperty(VM_VERSION_PROPERTY);
}
+ // EclipseLink still supports JDK <9 so using Runtime.Version to retrieve
+ // current JDK version is optional and can only be done trough reflection calls.
+ // TODO: Remove reflection after JDK <9 support is dropped.
+
+ /** JDK 9+ java.lang.Runtime.Version class name. */
+ private static final String VERSION_CLASS_NAME = "java.lang.Runtime$Version";
+
+ /** JDK 9+ java.lang.Runtime static version() method name. */
+ private static final String RUNTIME_VERSION_METHOD_NAME = "version";
+
/**
- * Java specification version detector.
- * Retrieves Java specification version from JDK system property. Version string should
- * look like:<ul>
+ * Invoke {@code Runtime#version()} method to retrieve {@code Runtime.Version} instance.
+ * @return {@code Runtime.Version} instance for JDK 9 and later or {@code null} otherwise.
+ */
+ private static Object runtimeVersionObject() {
+ try {
+ final Method m = Runtime.class.getMethod(RUNTIME_VERSION_METHOD_NAME);
+ return m.invoke(null);
+ // JDK <9, can't use java.lang.Runtime.Version. Just log with FINEST level and return null.
+ } catch (NoSuchMethodException e) {
+ AbstractSessionLog.getLog().log(SessionLog.FINEST, "javase_version_ex_method_not_found", new String[] {RUNTIME_VERSION_METHOD_NAME, Runtime.class.getName()});
+ // Shall never be thrown. Shall be logged as warning.
+ } catch (ReflectiveOperationException e) {
+ AbstractSessionLog.getLog().log(SessionLog.WARNING, "javase_version_ex_method_call", new String[] {RUNTIME_VERSION_METHOD_NAME, e.getClass().getName()});
+ }
+ return null;
+ }
+
+ /**
+ * Invoke {@code Runtime.Version} method with given name ({@code major} or {@code minor}) to retrieve version numbers.
+ * @param vClass {@code Runtime.Version} class.
+ * @param vObj {@code Runtime.Version} class instance containing JDK version information.
+ * @param name name of {@code Runtime.Version} instance method to invoke.
+ */
+ private static Integer getRuntimeVersionNumber(final Object vObj, final String name) {
+ try {
+ final Method m = vObj.getClass().getMethod(name);
+ return (Integer) m.invoke(vObj);
+ // Shall never be thrown. Shall be logged as warning.
+ } catch (ReflectiveOperationException e) {
+ AbstractSessionLog.getLog().log(SessionLog.WARNING, "javase_version_ex_method_call", new String[] {RUNTIME_VERSION_METHOD_NAME, e.getClass().getName()});
+ }
+ return null;
+ }
+
+ /**
+ * Retrieve JDK version numbers from {@code Runtime.Version} instance returned by {@code Runtime#version()} method.
+ * This works only for JDK 9 and later.
+ * @return Current JDK version for JDK 9 and later or {@code null} otherwise or when any problem with version retrieval happened.
+ */
+ private static JavaVersion runtimeVersion() {
+ final Object vObj = runtimeVersionObject();
+ if (vObj == null) {
+ return null;
+ }
+ final Integer major = getRuntimeVersionNumber(vObj, "major");
+ final Integer minor = getRuntimeVersionNumber(vObj, "minor");
+ if (major != null && minor != null) {
+ return new JavaVersion(major, minor);
+ }
+ return null;
+ }
+
+ /**
+ * Parse Java specification version from JDK system property provided as an argument.
+ * Version string should look like:<ul>
* <li/><code>"MA.MI"</code>
* </ul>
* Where<ul>
@@ -66,11 +130,10 @@ public static String vmVersionString() {
* <li/>MI is minor version number
* </ul>
* Label <code>java version</code> is parsed as non case sensitive.
+ * @return Current JDK version for any JDK from system property.
*/
- public static JavaVersion vmVersion() {
- final String version = vmVersionString();
- final Pattern pattern = Pattern.compile(VM_VERSION_PATTERN);
- final Matcher matcher = pattern.matcher(version);
+ private static JavaVersion propertyVersionParser(final String version) {
+ final Matcher matcher = VM_VERSION_PATTERN.matcher(version);
int major = 0, minor = 0;
if (matcher.find()) {
major = Integer.parseInt(matcher.group(1));
@@ -80,6 +143,22 @@ public static JavaVersion vmVersion() {
return new JavaVersion(major, minor);
}
+ /**
+ * Retrieve Java specification version from JDK system property.
+ * @return Current JDK version for any JDK from system property.
+ */
+ private static JavaVersion propertyVersion() {
+ return propertyVersionParser(vmVersionString());
+ }
+
+ /**
+ * Java specification version detector.
+ */
+ public static JavaVersion vmVersion() {
+ final JavaVersion version = runtimeVersion();
+ return version != null ? version : propertyVersion();
+ }
+
/** Major version number. */
private final int major;
@@ -147,7 +226,8 @@ public final String toString() {
/**
* Return {@link JavaSEPlatform} matching this Java SE specification version.
- * @return {@link JavaSEPlatform} matching this Java SE specification version.
+ * @return {@link JavaSEPlatform} matching this Java SE specification version
+ * or {@code JavaSEPlatform.DEFAULT} as default when platform matching fails.
*/
public final JavaSEPlatform toPlatform() {
return JavaSEPlatform.toValue(major, minor);
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/LoggingLocalizationResource.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/LoggingLocalizationResource.java
index d85edf8..32f8828 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/LoggingLocalizationResource.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/LoggingLocalizationResource.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle, IBM Corporation and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle, IBM Corporation and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -827,7 +827,9 @@ public class LoggingLocalizationResource extends ListResourceBundle {
{ "jaxp_sec_disabled", "Xml Security disabled, no JAXP {0} external access configuration necessary." },
{ "jaxp_sec_explicit", "Detected explicitly JAXP configuration, no JAXP {0} external access configuration necessary." },
{ "jaxp_sec_prop_supported", "Property {0} is supported and has been successfully set by used JAXP implementation." },
- { "jaxp_sec_prop_not_supported", "Property {0} is not supported by used JAXP implementation." }
+ { "jaxp_sec_prop_not_supported", "Property {0} is not supported by used JAXP implementation." },
+ { "javase_version_ex_method_not_found", "Method {0} was not found in {1}" },
+ { "javase_version_ex_method_call", "Exception when calling method {0}: {1}" }
};
/**