diff --git a/net/pom.xml b/net/pom.xml index 81392873..fc811b47 100644 --- a/net/pom.xml +++ b/net/pom.xml @@ -13,13 +13,18 @@ SmallRye Common: Net + + io.smallrye.common + smallrye-common-annotation + provided + io.smallrye.common smallrye-common-constraint - org.graalvm.sdk - nativeimage + io.smallrye.common + smallrye-common-os org.jboss.logging @@ -29,6 +34,10 @@ org.jboss.logging jboss-logging-annotations + + io.smallrye.ffm + smallrye-ffm + org.junit.jupiter junit-jupiter @@ -38,6 +47,10 @@ + + io.smallrye.ffm + smallrye-ffm-maven-plugin + maven-compiler-plugin @@ -49,6 +62,35 @@ + + maven-surefire-plugin + + + default-test + + --enable-native-access=io.smallrye.ffm,io.smallrye.common.net + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + **/module-info.java + + + + + net.revelc.code + impsort-maven-plugin + + + **/module-info.java + + + diff --git a/net/src/main/java/io/smallrye/common/net/HostName.java b/net/src/main/java/io/smallrye/common/net/HostName.java index 51cc0a77..3d259290 100644 --- a/net/src/main/java/io/smallrye/common/net/HostName.java +++ b/net/src/main/java/io/smallrye/common/net/HostName.java @@ -1,16 +1,26 @@ package io.smallrye.common.net; +import static io.smallrye.ffm.AsType.size_t; +import static io.smallrye.ffm.AsType.stdc_int; + import java.net.InetAddress; import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; import io.smallrye.common.constraint.Assert; +import io.smallrye.common.os.OS; +import io.smallrye.ffm.As; +import io.smallrye.ffm.Critical; +import io.smallrye.ffm.In; +import io.smallrye.ffm.Lib; +import io.smallrye.ffm.Link; +import io.smallrye.ffm.Out; /** * Methods for getting the system host name. The host name is detected from the environment, but may be overridden by * use of the {@code jboss.host.name} and/or {@code jboss.qualified.host.name} system properties. */ -@SuppressWarnings("removal") public final class HostName { private static final Object lock = new Object(); @@ -99,6 +109,33 @@ private static String[] resolveHosts() { if (qualifiedHostName == null) { // if host name is specified, don't pick a qualified host name that isn't related to it qualifiedHostName = providedHostName; + if (qualifiedHostName == null && Runtime.version().feature() >= 22) { + try { + switch (OS.current()) { + case MAC, LINUX, AIX, Z -> { + byte[] bytes = new byte[512]; + int res = gethostname(bytes, bytes.length); + if (res == 0) { + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == 0) { + qualifiedHostName = new String(bytes, 0, i, StandardCharsets.UTF_8); + break; + } + } + } + } + case WINDOWS -> { + char[] chars = new char[512]; + int[] lenBuf = new int[1]; + lenBuf[0] = chars.length; + if (GetComputerNameW(chars, lenBuf)) { + qualifiedHostName = new String(chars, 0, lenBuf[0]); + } + } + } + } catch (IllegalCallerException ignored) { + } + } if (qualifiedHostName == null) { // POSIX-like OSes including Mac should have this set qualifiedHostName = System.getenv("HOSTNAME"); @@ -110,8 +147,7 @@ private static String[] resolveHosts() { if (qualifiedHostName == null) { try { qualifiedHostName = HostName.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - qualifiedHostName = null; + } catch (UnknownHostException ignored) { } } if (qualifiedHostName != null @@ -141,4 +177,15 @@ private static String[] resolveHosts() { }; } + // POSIX + @Link + @As(stdc_int) + @Critical(heap = true) + private static native int gethostname(@Out byte[] buffer, @As(size_t) int bufLen); + + // Windows + @Link + @Critical(heap = true) + @Lib("kernel32") + private static native boolean GetComputerNameW(@Out char[] buffer, @In @Out int[] lenPtr); } diff --git a/net/src/main/java/io/smallrye/common/net/Substitutions.java b/net/src/main/java/io/smallrye/common/net/Substitutions.java deleted file mode 100644 index 46cc750e..00000000 --- a/net/src/main/java/io/smallrye/common/net/Substitutions.java +++ /dev/null @@ -1,104 +0,0 @@ -package io.smallrye.common.net; - -import java.net.UnknownHostException; -import java.util.Collections; -import java.util.List; - -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; -import org.graalvm.nativeimage.StackValue; -import org.graalvm.nativeimage.c.CContext; -import org.graalvm.nativeimage.c.function.CFunction; -import org.graalvm.nativeimage.c.type.CCharPointer; -import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.word.UnsignedWord; -import org.graalvm.word.WordFactory; - -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; - -final class Substitutions { - @TargetClass(className = "io.smallrye.common.net.GetHostInfoAction") - @Platforms({ Platform.DARWIN.class, Platform.LINUX.class }) - static final class Target_io_smallrye_common_net_GetHostInfoAction { - @Substitute - public String[] run() { - // still allow host name to be overridden - String qualifiedHostName = System.getProperty("jboss.qualified.host.name"); - String providedHostName = System.getProperty("jboss.host.name"); - String providedNodeName = System.getProperty("jboss.node.name"); - if (qualifiedHostName == null) { - // if host name is specified, don't pick a qualified host name that isn't related to it - qualifiedHostName = providedHostName; - if (qualifiedHostName == null) { - // query the operating system - CCharPointer nameBuf = StackValue.get(ProcessSubstitutions.SIZE); // should be more than enough - int res = NativeInfo.gethostname(nameBuf, WordFactory.unsigned(ProcessSubstitutions.SIZE)); - if (res > 0) { - if (res == ProcessSubstitutions.SIZE) { - // null-terminate a really long name - nameBuf.write(ProcessSubstitutions.SIZE - 1, (byte) 0); - } - qualifiedHostName = CTypeConversion.toJavaString(nameBuf); - } - } - if (qualifiedHostName == null) { - // POSIX-like OSes including Mac should have this set - qualifiedHostName = System.getenv("HOSTNAME"); - } - if (qualifiedHostName == null) { - // Certain versions of Windows - qualifiedHostName = System.getenv("COMPUTERNAME"); - } - if (qualifiedHostName == null) { - try { - qualifiedHostName = HostName.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - qualifiedHostName = null; - } - } - if (qualifiedHostName != null - && (Inet.isInet4Address(qualifiedHostName) || Inet.isInet6Address(qualifiedHostName))) { - // IP address is not acceptable - qualifiedHostName = null; - } - if (qualifiedHostName == null) { - // Give up - qualifiedHostName = "unknown-host.unknown-domain"; - } else { - qualifiedHostName = qualifiedHostName.trim().toLowerCase(); - } - } - if (providedHostName == null) { - // Use the host part of the qualified host name - final int idx = qualifiedHostName.indexOf('.'); - providedHostName = idx == -1 ? qualifiedHostName : qualifiedHostName.substring(0, idx); - } - if (providedNodeName == null) { - providedNodeName = providedHostName; - } - return new String[] { - providedHostName, - qualifiedHostName, - providedNodeName - }; - } - } - - @CContext(NativeInfoDirectives.class) - @Platforms({ Platform.DARWIN.class, Platform.LINUX.class }) - static final class NativeInfo { - @CFunction - static native int gethostname(CCharPointer nameBuf, UnsignedWord /* size_t */ len); - } - - static final class NativeInfoDirectives implements CContext.Directives { - public List getHeaderFiles() { - return Collections.singletonList(""); - } - } - - static final class ProcessSubstitutions { - static final int SIZE = 512; - } -} diff --git a/net/src/main/java/module-info.java b/net/src/main/java/module-info.java index cb00de31..9ab02493 100644 --- a/net/src/main/java/module-info.java +++ b/net/src/main/java/module-info.java @@ -1,12 +1,18 @@ +import io.smallrye.common.annotation.NativeAccess; + /** * Utilities for managing network addresses and information. */ +@NativeAccess module io.smallrye.common.net { requires io.smallrye.common.constraint; + requires io.smallrye.common.os; + requires static io.smallrye.common.annotation; + + requires io.smallrye.ffm; + requires org.jboss.logging; - requires static org.graalvm.nativeimage; - requires static org.graalvm.word; requires static org.jboss.logging.annotations; exports io.smallrye.common.net; -} \ No newline at end of file +} diff --git a/net/src/test/java/io/smallrye/common/net/HostNameTest.java b/net/src/test/java/io/smallrye/common/net/HostNameTest.java new file mode 100644 index 00000000..4d0aa73c --- /dev/null +++ b/net/src/test/java/io/smallrye/common/net/HostNameTest.java @@ -0,0 +1,12 @@ +package io.smallrye.common.net; + +import org.junit.jupiter.api.Test; + +public final class HostNameTest { + @Test + public void testHostName() { + System.out.println("Qualified name = " + HostName.getQualifiedHostName()); + System.out.println("Host name = " + HostName.getHostName()); + System.out.println("Node name = " + HostName.getNodeName()); + } +} diff --git a/pom.xml b/pom.xml index c9610dcf..7abbb5ea 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,7 @@ 4.5.34 5.1.0 2.0.0 + 0.3 3.6.0.Final @@ -98,6 +99,11 @@ ${version.graalvm} provided + + io.smallrye.ffm + smallrye-ffm + ${version.smallrye-ffm} + @@ -159,6 +165,19 @@ + + io.smallrye.ffm + smallrye-ffm-maven-plugin + ${version.smallrye-ffm} + + + process-ffm + + transform + + + + io.smallrye jandex-maven-plugin