From 2f0a50dbf3c0b2f2d71b274fba38b3b8f7c4fd99 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Fri, 10 Nov 2023 14:46:17 +0100 Subject: [PATCH] Add support for Windows extended socket options Support for this got added to JDK 17.0.10+1 and, thus, the GraalVM code needs to account for this change. Closes: #612 --- .../windows/WindowsNativeLibrarySupport.java | 6 +-- .../svm/core/jdk/WindowsExtNetHelper.java | 44 +++++++++++++++++++ .../svm/core/jni/JNILibraryInitializer.java | 5 ++- .../hosted/jdk/JNIRegistrationJavaNet.java | 7 +-- 4 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/WindowsExtNetHelper.java diff --git a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsNativeLibrarySupport.java b/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsNativeLibrarySupport.java index 0e751c203d73f..4d6c500500315 100644 --- a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsNativeLibrarySupport.java +++ b/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsNativeLibrarySupport.java @@ -26,7 +26,6 @@ import java.io.FileDescriptor; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.c.type.CCharPointer; @@ -45,6 +44,7 @@ import com.oracle.svm.core.jdk.Jvm; import com.oracle.svm.core.jdk.NativeLibrarySupport; import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport; +import com.oracle.svm.core.jdk.WindowsExtNetHelper; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.windows.headers.FileAPI; import com.oracle.svm.core.windows.headers.LibLoaderAPI; @@ -56,7 +56,7 @@ class WindowsNativeLibraryFeature implements InternalFeature { @Override public void duringSetup(DuringSetupAccess access) { - if (JavaVersionUtil.JAVA_SPEC >= 19) { + if (WindowsExtNetHelper.isExtendedNetSupported()) { NativeLibrarySupport.singleton().preregisterUninitializedBuiltinLibrary("extnet"); } } @@ -100,7 +100,7 @@ private static void loadNetLibrary() { } else { NativeLibrarySupport.singleton().registerInitializedBuiltinLibrary("net"); } - if (JavaVersionUtil.JAVA_SPEC >= 19) { + if (WindowsExtNetHelper.isExtendedNetSupported()) { NativeLibrarySupport.singleton().registerInitializedBuiltinLibrary("extnet"); System.loadLibrary("extnet"); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/WindowsExtNetHelper.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/WindowsExtNetHelper.java new file mode 100644 index 0000000000000..2c746aa6ba21c --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/WindowsExtNetHelper.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.svm.core.jdk; + +import org.graalvm.compiler.serviceprovider.GraalServices; +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; + +public class WindowsExtNetHelper { + + private WindowsExtNetHelper() { + // Don't instantiate + } + + public static boolean isExtendedNetSupported() { + // returns true if and only iff extended socket options are supported. This got + // implemented in JDK 19 (JDK-8284890) and then got backported to JDK 17.0.10 + // (JDK-8308593) both needing extnet library. + return JavaVersionUtil.JAVA_SPEC >= 19 || + (JavaVersionUtil.JAVA_SPEC == 17 && GraalServices.getJavaUpdateVersion() >= 10); + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java index fbb4915d69b4f..563962e235f94 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java @@ -43,6 +43,7 @@ import com.oracle.svm.core.c.CGlobalDataFactory; import com.oracle.svm.core.jdk.NativeLibrarySupport; import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport; +import com.oracle.svm.core.jdk.WindowsExtNetHelper; import com.oracle.svm.core.jni.functions.JNIFunctionTables; import com.oracle.svm.core.jni.headers.JNIJavaVM; import com.oracle.svm.core.jni.headers.JNIVersion; @@ -87,8 +88,8 @@ public boolean fillCGlobalDataMap(Collection staticLibNames) { // TODO: This check should be removed when all static libs will have JNI_OnLoad function ArrayList localStaticLibNames = new ArrayList<>(staticLibNames); localStaticLibNames.retainAll(libsWithOnLoad); - if (JavaVersionUtil.JAVA_SPEC >= 19 && Platform.includedIn(Platform.WINDOWS.class)) { - /* libextnet on Windows (introduced in Java 19) does not contain an OnLoad method. */ + if (WindowsExtNetHelper.isExtendedNetSupported() && Platform.includedIn(Platform.WINDOWS.class)) { + /* libextnet on Windows does not contain an OnLoad method. */ localStaticLibNames.remove("extnet"); } boolean mapIsChanged = false; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java index 24ea9c561fdf9..0376c2cd2a2b4 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java @@ -40,6 +40,7 @@ import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.jdk.JNIRegistrationUtil; +import com.oracle.svm.core.jdk.WindowsExtNetHelper; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.util.ReflectionUtil; @@ -74,10 +75,10 @@ public void duringSetup(DuringSetupAccess a) { } } - if (this.hasPlatformSocketOptions && (isPosix() || JavaVersionUtil.JAVA_SPEC >= 19)) { + if (this.hasPlatformSocketOptions && (isPosix() || WindowsExtNetHelper.isExtendedNetSupported())) { /* * The libextnet was actually introduced in Java 9, but the support for Linux, Darwin - * and Windows was added later in Java 10, Java 11 and Java 19 respectively. + * and Windows was added later in Java 10, Java 11 and Java 17 respectively. */ rerunClassInit(a, "jdk.net.ExtendedSocketOptions", "jdk.net.ExtendedSocketOptions$PlatformSocketOptions", "sun.net.ext.ExtendedSocketOptions"); } @@ -158,7 +159,7 @@ public void beforeAnalysis(BeforeAnalysisAccess a) { method(a, "java.net.PlainSocketImpl", "localAddress", int.class, clazz(a, "java.net.InetAddressContainer"))); } } - if (this.hasPlatformSocketOptions && (isPosix() || JavaVersionUtil.JAVA_SPEC >= 19)) { + if (this.hasPlatformSocketOptions && (isPosix() || WindowsExtNetHelper.isExtendedNetSupported())) { /* Support for the libextnet. */ a.registerReachabilityHandler(JNIRegistrationJavaNet::registerPlatformSocketOptionsCreate, method(a, "jdk.net.ExtendedSocketOptions$PlatformSocketOptions", "create"));