This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch java-impl-static-linking
in repository https://gitbox.apache.org/repos/asf/freemarker.git

commit 3b462a5f78fe263ada4ab6609bb5cad2ef9e1231
Author: ddekany <[email protected]>
AuthorDate: Tue Jun 4 09:05:52 2024 +0200

    Statically linked JavaNImpl classes, utilizing "JEP 238: Multi-Release JAR 
Files"
---
 build.gradle.kts                                   |  5 +-
 .../src/main/java/freemarker/core/_Java16.java     |  9 ++
 .../core/{_Java16.java => _Java16Impl.java}        | 24 +++++-
 .../src/main/java/freemarker/core/_Java9.java      |  9 ++
 .../core/{_Java16.java => _Java9Impl.java}         | 22 +++--
 .../main/java/freemarker/core/_JavaVersions.java   | 95 ----------------------
 .../freemarker/ext/beans/ClassIntrospector.java    |  9 +-
 .../ext/beans/ClassIntrospectorBuilder.java        |  9 +-
 .../src/main/java/freemarker/core/_Java16Impl.java | 13 ++-
 .../beans/Java16TestClassLoadingCorrectTest.java   | 23 +++---
 .../ext/beans/NotExportedInternalPackageTest.java  |  3 +
 .../src/main/java/freemarker/core/_Java9Impl.java  | 13 ++-
 .../test/java/freemarker/core/Java9ImplTest.java   | 10 +--
 .../core/Java9TestClassLoadingCorrectTest.java     | 22 ++---
 14 files changed, 109 insertions(+), 157 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index 85309947..e2575431 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -20,7 +20,7 @@
 import java.io.FileOutputStream
 import java.nio.charset.StandardCharsets
 import java.nio.file.Files
-import java.util.Properties
+import java.util.*
 import java.util.stream.Collectors
 
 plugins {
@@ -144,6 +144,9 @@ tasks.sourcesJar.configure {
         into("META-INF")
     }
 
+    exclude("freemarker/core/_Java9Impl.java")
+    exclude("freemarker/core/_Java16Impl.java")
+
     // Depend on the createBuildInfo task and include the generated file
     dependsOn(createBuildInfo)
     from(buildInfoFile())
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java16.java 
b/freemarker-core/src/main/java/freemarker/core/_Java16.java
index 19de70a3..396c83bb 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java16.java
+++ b/freemarker-core/src/main/java/freemarker/core/_Java16.java
@@ -26,6 +26,15 @@ import java.util.Set;
  * Used for accessing functionality that's only present in Java 16 or later.
  */
 public interface _Java16 {
+    /**
+     * Using "JEP 238: Multi-Release JAR Files", links to the proper version 
of the {@link _Java16Impl} class.
+     */
+    _Java16 INSTANCE = new _Java16Impl();
+
+    /**
+     * Tells if Java 16 features can be used in the current run-time 
environment.
+     */
+    boolean isSupported();
 
     boolean isRecord(Class<?> cl);
 
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java16.java 
b/freemarker-core/src/main/java/freemarker/core/_Java16Impl.java
similarity index 55%
copy from freemarker-core/src/main/java/freemarker/core/_Java16.java
copy to freemarker-core/src/main/java/freemarker/core/_Java16Impl.java
index 19de70a3..5ae2f102 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java16.java
+++ b/freemarker-core/src/main/java/freemarker/core/_Java16Impl.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package freemarker.core;
 
 import java.lang.reflect.Method;
@@ -23,12 +24,27 @@ import java.util.Set;
 
 /**
  * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 16 or later.
+ * Pre-Java-16 implementation of {@link _Java16}.
  */
-public interface _Java16 {
+// We also have a Java 16 versions of this class in freemarker-core16, and we 
put all versions into
+// the jar artifact via "JEP 238: Multi-Release JAR Files".
+public final class _Java16Impl implements _Java16 {
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
 
-    boolean isRecord(Class<?> cl);
+    @Override
+    public boolean isRecord(Class<?> cl) {
+        throw newNoRecordSupportException();
+    }
 
-    Set<Method> getComponentAccessors(Class<?> recordClass);
+    @Override
+    public Set<Method> getComponentAccessors(Class<?> recordClass){
+        throw newNoRecordSupportException();
+    }
 
+    private UnsupportedOperationException newNoRecordSupportException() {
+        return new UnsupportedOperationException("Record support needs at 
least Java 16");
+    }
 }
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java9.java 
b/freemarker-core/src/main/java/freemarker/core/_Java9.java
index 6f1a56ee..a446848f 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java9.java
+++ b/freemarker-core/src/main/java/freemarker/core/_Java9.java
@@ -23,6 +23,15 @@ package freemarker.core;
  * Used for accessing functionality that's only present in Java 9 or later.
  */
 public interface _Java9 {
+    /**
+     * Using "JEP 238: Multi-Release JAR Files", links to the proper version 
of the {@link _Java9Impl} class.
+     */
+    _Java9 INSTANCE = new _Java9Impl();
+
+    /**
+     * Tells if Java 9 features can be used in the current run-time 
environment.
+     */
+    boolean isSupported();
 
     boolean isAccessibleAccordingToModuleExports(Class<?> m);
 
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java16.java 
b/freemarker-core/src/main/java/freemarker/core/_Java9Impl.java
similarity index 64%
copy from freemarker-core/src/main/java/freemarker/core/_Java16.java
copy to freemarker-core/src/main/java/freemarker/core/_Java9Impl.java
index 19de70a3..68b16761 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java16.java
+++ b/freemarker-core/src/main/java/freemarker/core/_Java9Impl.java
@@ -16,19 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package freemarker.core;
 
-import java.lang.reflect.Method;
-import java.util.Set;
+package freemarker.core;
 
 /**
  * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 16 or later.
+ * Pre-Java-9 implementation of {@link _Java9}.
  */
-public interface _Java16 {
-
-    boolean isRecord(Class<?> cl);
-
-    Set<Method> getComponentAccessors(Class<?> recordClass);
+// We also have a Java 9 versions of this class in freemarker-core9, and we 
put all versions into
+// the jar artifact via "JEP 238: Multi-Release JAR Files".
+public class _Java9Impl implements _Java9 {
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
 
+    @Override
+    public boolean isAccessibleAccordingToModuleExports(Class<?> m) {
+        throw new UnsupportedOperationException("Requires at least Java 9");
+    }
 }
diff --git a/freemarker-core/src/main/java/freemarker/core/_JavaVersions.java 
b/freemarker-core/src/main/java/freemarker/core/_JavaVersions.java
deleted file mode 100644
index 4a3957e4..00000000
--- a/freemarker-core/src/main/java/freemarker/core/_JavaVersions.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 freemarker.core;
-
-import freemarker.log.Logger;
-import freemarker.template.Version;
-import freemarker.template.utility.SecurityUtilities;
-
-/**
- * Used internally only, might change without notice!
- */
-public final class _JavaVersions {
-    
-    private _JavaVersions() {
-        // Not meant to be instantiated
-    }
-
-    /**
-     * {@code null} if Java 9 is not available, otherwise the object through 
with the Java 9 operations are available.
-     */
-    static public final _Java9 JAVA_9 = isAtLeast(9, "java.lang.Module")
-            ? tryLoadJavaSupportSingleton(9, _Java9.class)
-            : null;
-
-    /**
-     * {@code null} if Java 16 is not available, otherwise the object through 
with the Java 16 operations are available.
-     */
-    static public final _Java16 JAVA_16 = isAtLeast(16, 
"java.net.UnixDomainSocketAddress")
-            ? tryLoadJavaSupportSingleton(16, _Java16.class)
-            : null;
-
-    @SuppressWarnings("unchecked")
-    private static <T> T tryLoadJavaSupportSingleton(int javaVersion, Class<T> 
javaSupportInterface) {
-        String implClassName = "freemarker.core._Java" + javaVersion + "Impl";
-        try {
-            return (T) Class.forName(implClassName)
-                    .getField("INSTANCE")
-                    .get(null);
-        } catch (Exception e) {
-            try {
-                if (e instanceof ClassNotFoundException) {
-                    // Happens when we run JUnit tests
-                    Logger.getLogger("freemarker.runtime").warn(
-                            "Seems that the Java " + javaVersion + " support 
class (" + implClassName
-                                    + ") wasn't included in the build");
-                } else {
-                    Logger.getLogger("freemarker.runtime").error(
-                            "Failed to load Java " + javaVersion + " support 
class",
-                            e);
-                }
-            } catch (Exception e2) {
-                // Suppressed
-            }
-            return null;
-        }
-    }
-
-    private static boolean isAtLeast(int minimumMajorVersion, String 
proofClassPresence) {
-        boolean result = false;
-        String vStr = SecurityUtilities.getSystemProperty("java.version", 
null);
-        if (vStr != null) {
-            try {
-                Version v = new Version(vStr);
-                result = v.getMajor() >= minimumMajorVersion;
-            } catch (Exception e) {
-                // Ignore
-            }
-        } else {
-            try {
-                Class.forName(proofClassPresence);
-                result = true;
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
-        return result;
-    }
-
-}
diff --git 
a/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospector.java 
b/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index 45f76de7..5e229937 100644
--- a/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -48,7 +48,8 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import freemarker.core.BugException;
-import freemarker.core._JavaVersions;
+import freemarker.core._Java16;
+import freemarker.core._Java9;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
 import freemarker.ext.util.ModelCache;
@@ -200,7 +201,7 @@ class ClassIntrospector {
         this.defaultZeroArgumentNonVoidMethodPolicy = 
builder.getDefaultZeroArgumentNonVoidMethodPolicy();
         this.recordZeroArgumentNonVoidMethodPolicy = 
builder.getRecordZeroArgumentNonVoidMethodPolicy();
         this.recordAware = defaultZeroArgumentNonVoidMethodPolicy != 
recordZeroArgumentNonVoidMethodPolicy;
-        if (recordAware && _JavaVersions.JAVA_16 == null) {
+        if (recordAware && !_Java16.INSTANCE.isSupported()) {
             throw new IllegalArgumentException(
                     "defaultZeroArgumentNonVoidMethodPolicy != 
recordZeroArgumentNonVoidMethodPolicy, " +
                     "but record support is not available (as Java 16 support 
is not available).");
@@ -343,7 +344,7 @@ class ClassIntrospector {
             ClassMemberAccessPolicy effClassMemberAccessPolicy) throws 
IntrospectionException {
         BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
 
-        boolean treatClassAsRecord = recordAware && 
_JavaVersions.JAVA_16.isRecord(clazz);
+        boolean treatClassAsRecord = recordAware && 
_Java16.INSTANCE.isRecord(clazz);
         ZeroArgumentNonVoidMethodPolicy zeroArgumentNonVoidMethodPolicy = 
treatClassAsRecord
                 ? recordZeroArgumentNonVoidMethodPolicy
                 : defaultZeroArgumentNonVoidMethodPolicy;
@@ -835,7 +836,7 @@ class ClassIntrospector {
     private static void discoverAccessibleMethods(
             Class<?> clazz, Map<ExecutableMemberSignature, List<Method>> 
accessibles) {
         if (Modifier.isPublic(clazz.getModifiers())
-                && (_JavaVersions.JAVA_9 == null || 
_JavaVersions.JAVA_9.isAccessibleAccordingToModuleExports(clazz))) {
+                && (!_Java9.INSTANCE.isSupported() || 
_Java9.INSTANCE.isAccessibleAccordingToModuleExports(clazz))) {
             try {
                 Method[] methods = clazz.getMethods();
                 for (int i = 0; i < methods.length; i++) {
diff --git 
a/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
 
b/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
index 7ff87072..141917cc 100644
--- 
a/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
+++ 
b/freemarker-core/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
@@ -26,7 +26,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
-import freemarker.core._JavaVersions;
+import freemarker.core._Java16;
 import freemarker.template.Configuration;
 import freemarker.template.Version;
 import freemarker.template._TemplateAPI;
@@ -76,9 +76,10 @@ final class ClassIntrospectorBuilder implements Cloneable {
         this.incompatibleImprovements = 
normalizeIncompatibleImprovementsVersion(incompatibleImprovements);
         treatDefaultMethodsAsBeanMembers = incompatibleImprovements.intValue() 
>= _VersionInts.V_2_3_26;
         defaultZeroArgumentNonVoidMethodPolicy = 
ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY;
-        recordZeroArgumentNonVoidMethodPolicy = 
incompatibleImprovements.intValue() >= _VersionInts.V_2_3_33 && 
_JavaVersions.JAVA_16 != null
-                ? 
ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD
-                : defaultZeroArgumentNonVoidMethodPolicy;
+        recordZeroArgumentNonVoidMethodPolicy
+                = incompatibleImprovements.intValue() >= _VersionInts.V_2_3_33 
&& _Java16.INSTANCE.isSupported()
+                        ? 
ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD
+                        : defaultZeroArgumentNonVoidMethodPolicy;
         memberAccessPolicy = 
DefaultMemberAccessPolicy.getInstance(this.incompatibleImprovements);
     }
 
diff --git a/freemarker-core16/src/main/java/freemarker/core/_Java16Impl.java 
b/freemarker-core16/src/main/java/freemarker/core/_Java16Impl.java
index ba1ba879..e498f8c3 100644
--- a/freemarker-core16/src/main/java/freemarker/core/_Java16Impl.java
+++ b/freemarker-core16/src/main/java/freemarker/core/_Java16Impl.java
@@ -25,16 +25,15 @@ import java.util.Set;
 
 /**
  * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 16 or later.
+ * Java 16 implementation of {@link _Java16}.
  */
-// Compile this against Java 16
+// We also have a pre-Java-16 versions of this class in freemarker-core, and 
we put all versions into
+// the jar artifact via "JEP 238: Multi-Release JAR Files".
 @SuppressWarnings("Since15") // For IntelliJ inspection
 public class _Java16Impl implements _Java16 {
-
-    public static final _Java16 INSTANCE = new _Java16Impl();
-
-    private _Java16Impl() {
-        // Not meant to be instantiated
+    @Override
+    public boolean isSupported() {
+        return true;
     }
 
     @Override
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java16.java 
b/freemarker-core16/src/test/java/freemarker/ext/beans/Java16TestClassLoadingCorrectTest.java
similarity index 57%
copy from freemarker-core/src/main/java/freemarker/core/_Java16.java
copy to 
freemarker-core16/src/test/java/freemarker/ext/beans/Java16TestClassLoadingCorrectTest.java
index 19de70a3..d4f4f020 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java16.java
+++ 
b/freemarker-core16/src/test/java/freemarker/ext/beans/Java16TestClassLoadingCorrectTest.java
@@ -16,19 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package freemarker.core;
 
-import java.lang.reflect.Method;
-import java.util.Set;
+package freemarker.ext.beans;
 
-/**
- * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 16 or later.
- */
-public interface _Java16 {
+import static org.junit.Assert.*;
 
-    boolean isRecord(Class<?> cl);
+import org.junit.Test;
 
-    Set<Method> getComponentAccessors(Class<?> recordClass);
+import freemarker.core._Java16;
+import freemarker.core._Java16Impl;
 
+public class Java16TestClassLoadingCorrectTest {
+    @Test
+    public void java16Supported() {
+        // This can be a problem if the test is not ran from the jar, and the 
impl class from the core takes precedence
+        assertTrue(
+                "Multi-Release JAR selection of the proper " + 
_Java16Impl.class.getName() + " variant didn't happen in the Java 16 test 
environment",
+                _Java16.INSTANCE.isSupported());
+    }
 }
diff --git 
a/freemarker-core16/src/test/java/freemarker/ext/beans/NotExportedInternalPackageTest.java
 
b/freemarker-core16/src/test/java/freemarker/ext/beans/NotExportedInternalPackageTest.java
index 117544cc..38a7f131 100644
--- 
a/freemarker-core16/src/test/java/freemarker/ext/beans/NotExportedInternalPackageTest.java
+++ 
b/freemarker-core16/src/test/java/freemarker/ext/beans/NotExportedInternalPackageTest.java
@@ -33,6 +33,7 @@ import org.junit.Test;
 import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
 
+import freemarker.core._Java16;
 import freemarker.template.TemplateHashModel;
 import freemarker.template.TemplateMethodModelEx;
 
@@ -42,6 +43,8 @@ import freemarker.template.TemplateMethodModelEx;
 public class NotExportedInternalPackageTest {
     @Test
     public void java16InternalClassAvoidanceTest() throws Exception {
+        assertTrue(_Java16.INSTANCE.isSupported());
+
         BeansWrapper bw = new BeansWrapper();
 
         Document document = 
DocumentBuilderFactory.newInstance().newDocumentBuilder()
diff --git a/freemarker-core9/src/main/java/freemarker/core/_Java9Impl.java 
b/freemarker-core9/src/main/java/freemarker/core/_Java9Impl.java
index 1f5182af..aabc49cc 100644
--- a/freemarker-core9/src/main/java/freemarker/core/_Java9Impl.java
+++ b/freemarker-core9/src/main/java/freemarker/core/_Java9Impl.java
@@ -22,18 +22,17 @@ import freemarker.ext.beans.BeansWrapper;
 
 /**
  * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 9 or later.
+ * Java 9 implementation of {@link _Java9}.
  */
-// Compile this against Java 9
+// We also have a pre-Java-9 versions of this class in freemarker-core, and we 
put all versions into
+// the jar artifact via "JEP 238: Multi-Release JAR Files".
 @SuppressWarnings("Since15") // For IntelliJ inspection
 public class _Java9Impl implements _Java9 {
-
-    public static final _Java9 INSTANCE = new _Java9Impl();
-
     private static final Module ACCESSOR_MODULE = 
BeansWrapper.class.getModule();
 
-    private _Java9Impl() {
-        // Not meant to be instantiated
+    @Override
+    public boolean isSupported() {
+        return true;
     }
 
     @Override
diff --git a/freemarker-core9/src/test/java/freemarker/core/Java9ImplTest.java 
b/freemarker-core9/src/test/java/freemarker/core/Java9ImplTest.java
index 9612d5ba..12807460 100644
--- a/freemarker-core9/src/test/java/freemarker/core/Java9ImplTest.java
+++ b/freemarker-core9/src/test/java/freemarker/core/Java9ImplTest.java
@@ -38,11 +38,11 @@ public class Java9ImplTest {
 
     @Test
     public void testIsAccessibleAccordingToModuleExports() throws Exception {
-        assertNotNull(_JavaVersions.JAVA_9);
-        
assertTrue(_JavaVersions.JAVA_9.isAccessibleAccordingToModuleExports(Document.class));
-        
assertFalse(_JavaVersions.JAVA_9.isAccessibleAccordingToModuleExports(getSomeInternalClass()));
-        
assertTrue(_JavaVersions.JAVA_9.isAccessibleAccordingToModuleExports(String[].class));
-        
assertTrue(_JavaVersions.JAVA_9.isAccessibleAccordingToModuleExports(int.class));
+        assertTrue(_Java9.INSTANCE.isSupported());
+        
assertTrue(_Java9.INSTANCE.isAccessibleAccordingToModuleExports(Document.class));
+        
assertFalse(_Java9.INSTANCE.isAccessibleAccordingToModuleExports(getSomeInternalClass()));
+        
assertTrue(_Java9.INSTANCE.isAccessibleAccordingToModuleExports(String[].class));
+        
assertTrue(_Java9.INSTANCE.isAccessibleAccordingToModuleExports(int.class));
     }
 
     private static Class<?> getSomeInternalClass() throws SAXException, 
IOException, ParserConfigurationException,
diff --git a/freemarker-core/src/main/java/freemarker/core/_Java16.java 
b/freemarker-core9/src/test/java/freemarker/core/Java9TestClassLoadingCorrectTest.java
similarity index 62%
copy from freemarker-core/src/main/java/freemarker/core/_Java16.java
copy to 
freemarker-core9/src/test/java/freemarker/core/Java9TestClassLoadingCorrectTest.java
index 19de70a3..5ef21763 100644
--- a/freemarker-core/src/main/java/freemarker/core/_Java16.java
+++ 
b/freemarker-core9/src/test/java/freemarker/core/Java9TestClassLoadingCorrectTest.java
@@ -16,19 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package freemarker.core;
-
-import java.lang.reflect.Method;
-import java.util.Set;
 
-/**
- * Used internally only, might change without notice!
- * Used for accessing functionality that's only present in Java 16 or later.
- */
-public interface _Java16 {
+package freemarker.core;
 
-    boolean isRecord(Class<?> cl);
+import static org.junit.Assert.*;
 
-    Set<Method> getComponentAccessors(Class<?> recordClass);
+import org.junit.Test;
 
+public class Java9TestClassLoadingCorrectTest {
+    @Test
+    public void java9Supported() {
+        // This can be a problem if the test is not ran from the jar, and the 
impl class from the core takes precedence
+        assertTrue(
+                "Multi-Release JAR selection of the proper " + 
_Java9Impl.class.getName() + " variant didn't happen in the Java 9 test 
environment",
+                _Java9.INSTANCE.isSupported());
+    }
 }

Reply via email to