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

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kyuubi.git


The following commit(s) were added to refs/heads/master by this push:
     new 315adda35 [KYUUBI #6499] Rewrite some utility methods in Java
315adda35 is described below

commit 315adda3539bcfab2bb2b9cb2ac6882f8444721c
Author: Cheng Pan <[email protected]>
AuthorDate: Tue Jun 25 09:59:03 2024 +0800

    [KYUUBI #6499] Rewrite some utility methods in Java
    
    # :mag: Description
    
    This PR rewrites some utility methods in Java, specifically,
    ```
    Utils.isWindows
    Utils.isMac
    Utils.findLocalInetAddress
    ```
    
    and moves them from `kyuubi-common`'s `Utils` to the `kyuubi-util`'s 
`JavaUtils`, so that they could be used in other modules that do not depend on 
`kyuubi-common`.
    
    ## Types of changes :bookmark:
    
    - [ ] Bugfix (non-breaking change which fixes an issue)
    - [ ] New feature (non-breaking change which adds functionality)
    - [ ] Breaking change (fix or feature that would cause existing 
functionality to change)
    
    ## Test Plan ๐Ÿงช
    
    Pass GHA.
    
    ---
    
    # Checklist ๐Ÿ“
    
    - [x] This patch was not authored or co-authored using [Generative 
Tooling](https://www.apache.org/legal/generative-tooling.html)
    
    **Be nice. Be informative.**
    
    Closes #6499 from pan3793/javautils.
    
    Closes #6499
    
    565936def [Cheng Pan] fix
    f06a85e9f [Cheng Pan] Move some untiliy methods in Java
    
    Authored-by: Cheng Pan <[email protected]>
    Signed-off-by: Cheng Pan <[email protected]>
---
 .../kyuubi/engine/spark/SparkSQLEngine.scala       |  4 +-
 .../deployment/KyuubiOnKubernetesTestsSuite.scala  |  5 +-
 .../test/spark/SparkOnKubernetesTestsSuite.scala   |  3 +-
 .../src/main/scala/org/apache/kyuubi/Utils.scala   | 55 ---------------------
 .../apache/kyuubi/service/TFrontendService.scala   |  6 +--
 .../test/scala/org/apache/kyuubi/UtilsSuite.scala  | 10 ----
 .../hs2connection/UserHS2ConnectionFileParser.java |  3 +-
 .../kyuubi/engine/spark/SparkProcessBuilder.scala  |  5 +-
 .../kyuubi/server/KyuubiMySQLFrontendService.scala |  4 +-
 .../kyuubi/server/KyuubiRestFrontendService.scala  |  8 +--
 .../kyuubi/server/KyuubiTrinoFrontendService.scala |  9 ++--
 .../org/apache/kyuubi/server/ui/JettyServer.scala  |  4 +-
 kyuubi-util/pom.xml                                |  5 ++
 .../java/org/apache/kyuubi/util/JavaUtils.java     | 57 +++++++++++++++++++++-
 .../org/apache/kyuubi/util/JavaUtilsTest.java}     | 23 ++++++---
 .../kyuubi/zookeeper/EmbeddedZookeeper.scala       |  5 +-
 16 files changed, 107 insertions(+), 99 deletions(-)

diff --git 
a/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/SparkSQLEngine.scala
 
b/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/SparkSQLEngine.scala
index 2d7367fe5..a78b13c1b 100644
--- 
a/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/SparkSQLEngine.scala
+++ 
b/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/SparkSQLEngine.scala
@@ -45,7 +45,7 @@ import org.apache.kyuubi.ha.HighAvailabilityConf._
 import org.apache.kyuubi.ha.client.RetryPolicies
 import org.apache.kyuubi.service.Serverable
 import org.apache.kyuubi.session.SessionHandle
-import org.apache.kyuubi.util.{SignalRegister, ThreadUtils}
+import org.apache.kyuubi.util.{JavaUtils, SignalRegister, ThreadUtils}
 import 
org.apache.kyuubi.util.ThreadUtils.scheduleTolerableRunnableWithFixedDelay
 
 case class SparkSQLEngine(spark: SparkSession) extends 
Serverable("SparkSQLEngine") {
@@ -296,7 +296,7 @@ object SparkSQLEngine extends Logging {
 
       if (!isOnK8sClusterMode) {
         // set driver host to ip instead of kyuubi pod name
-        _sparkConf.setIfMissing("spark.driver.host", 
Utils.findLocalInetAddress.getHostAddress)
+        _sparkConf.setIfMissing("spark.driver.host", 
JavaUtils.findLocalInetAddress.getHostAddress)
       }
     }
 
diff --git 
a/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/deployment/KyuubiOnKubernetesTestsSuite.scala
 
b/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/deployment/KyuubiOnKubernetesTestsSuite.scala
index 6ffd157d6..319b1bfe5 100644
--- 
a/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/deployment/KyuubiOnKubernetesTestsSuite.scala
+++ 
b/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/deployment/KyuubiOnKubernetesTestsSuite.scala
@@ -22,10 +22,11 @@ import org.apache.hadoop.fs.{FileSystem, Path}
 import org.apache.hadoop.fs.permission.{FsAction, FsPermission}
 import org.apache.hadoop.net.NetUtils
 
-import org.apache.kyuubi.{Utils, WithSimpleDFSService}
+import org.apache.kyuubi.WithSimpleDFSService
 import org.apache.kyuubi.config.KyuubiConf.FRONTEND_THRIFT_BINARY_BIND_HOST
 import org.apache.kyuubi.kubernetes.test.WithKyuubiServerOnKubernetes
 import org.apache.kyuubi.operation.SparkQueryTests
+import org.apache.kyuubi.util.JavaUtils
 import org.apache.kyuubi.zookeeper.ZookeeperConf.ZK_CLIENT_PORT_ADDRESS
 
 /**
@@ -109,7 +110,7 @@ class KyuubiOnKubernetesWithClientSparkTestsSuite
  */
 class KyuubiOnKubernetesWithClusterSparkTestsSuite
   extends KyuubiOnKubernetesWithSparkTestsBase with WithSimpleDFSService with 
SparkQueryTests {
-  private val localhostAddress = Utils.findLocalInetAddress.getHostAddress
+  private val localhostAddress = JavaUtils.findLocalInetAddress.getHostAddress
   private val driverTemplate =
     Thread.currentThread().getContextClassLoader.getResource("driver.yml")
 
diff --git 
a/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/spark/SparkOnKubernetesTestsSuite.scala
 
b/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/spark/SparkOnKubernetesTestsSuite.scala
index be07dd557..4692581cc 100644
--- 
a/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/spark/SparkOnKubernetesTestsSuite.scala
+++ 
b/integration-tests/kyuubi-kubernetes-it/src/test/scala/org/apache/kyuubi/kubernetes/test/spark/SparkOnKubernetesTestsSuite.scala
@@ -34,6 +34,7 @@ import org.apache.kyuubi.engine.spark.SparkProcessBuilder
 import org.apache.kyuubi.kubernetes.test.MiniKube
 import org.apache.kyuubi.operation.SparkQueryTests
 import org.apache.kyuubi.session.KyuubiSessionManager
+import org.apache.kyuubi.util.JavaUtils
 import org.apache.kyuubi.util.Validator.KUBERNETES_EXECUTOR_POD_NAME_PREFIX
 import org.apache.kyuubi.zookeeper.ZookeeperConf.ZK_CLIENT_PORT_ADDRESS
 
@@ -96,7 +97,7 @@ class SparkClientModeOnKubernetesSuite extends 
SparkClientModeOnKubernetesSuiteB
  */
 class SparkClusterModeOnKubernetesSuiteBase
   extends SparkOnKubernetesSuiteBase with WithSimpleDFSService {
-  private val localhostAddress = Utils.findLocalInetAddress.getHostAddress
+  private val localhostAddress = JavaUtils.findLocalInetAddress.getHostAddress
   private val driverTemplate =
     Thread.currentThread().getContextClassLoader.getResource("driver.yml")
 
diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/Utils.scala 
b/kyuubi-common/src/main/scala/org/apache/kyuubi/Utils.scala
index f0b0fea91..5944e9f97 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/Utils.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/Utils.scala
@@ -18,7 +18,6 @@
 package org.apache.kyuubi
 
 import java.io._
-import java.net.{Inet4Address, InetAddress, NetworkInterface}
 import java.nio.charset.StandardCharsets
 import java.nio.file.{Files, Path, Paths, StandardCopyOption}
 import java.security.PrivilegedAction
@@ -33,7 +32,6 @@ import scala.sys.process._
 import scala.util.control.NonFatal
 import scala.util.matching.Regex
 
-import org.apache.commons.lang3.SystemUtils
 import org.apache.commons.lang3.time.DateFormatUtils
 import org.apache.hadoop.security.UserGroupInformation
 import org.apache.hadoop.util.ShutdownHookManager
@@ -224,31 +222,6 @@ object Utils extends Logging {
     })
   }
 
-  private val shortVersionRegex = """^(\d+\.\d+\.\d+)(.*)?$""".r
-
-  /**
-   * Given a Kyuubi/Spark/Hive version string, return the short version string.
-   * E.g., for 3.0.0-SNAPSHOT, return '3.0.0'.
-   */
-  def shortVersion(version: String): String = {
-    shortVersionRegex.findFirstMatchIn(version) match {
-      case Some(m) => m.group(1)
-      case None =>
-        throw new IllegalArgumentException(s"Tried to parse '$version' as a 
project" +
-          s" version string, but it could not find the major/minor/maintenance 
version numbers.")
-    }
-  }
-
-  /**
-   * Whether the underlying operating system is Windows.
-   */
-  val isWindows: Boolean = SystemUtils.IS_OS_WINDOWS
-
-  /**
-   * Whether the underlying operating system is MacOS.
-   */
-  val isMac: Boolean = SystemUtils.IS_OS_MAC
-
   /**
    * Indicates whether Kyuubi is currently running unit tests.
    */
@@ -274,34 +247,6 @@ object Utils extends Logging {
     ShutdownHookManager.get().addShutdownHook(hook, priority)
   }
 
-  /**
-   * This block of code is based on Spark's Utils.findLocalInetAddress()
-   */
-  def findLocalInetAddress: InetAddress = {
-    val address = InetAddress.getLocalHost
-    if (address.isLoopbackAddress) {
-      val activeNetworkIFs = 
NetworkInterface.getNetworkInterfaces.asScala.toSeq
-      val reOrderedNetworkIFs = if (isWindows) activeNetworkIFs else 
activeNetworkIFs.reverse
-
-      for (ni <- reOrderedNetworkIFs) {
-        val addresses = ni.getInetAddresses.asScala
-          .filterNot(addr => addr.isLinkLocalAddress || 
addr.isLoopbackAddress).toSeq
-        if (addresses.nonEmpty) {
-          val addr = 
addresses.find(_.isInstanceOf[Inet4Address]).getOrElse(addresses.head)
-          // because of Inet6Address.toHostName may add interface at the end 
if it knows about it
-          val strippedAddress = InetAddress.getByAddress(addr.getAddress)
-          // We've found an address that looks reasonable!
-          warn(s"${address.getHostName} was resolved to a loopback address: " +
-            s"${address.getHostAddress}, using 
${strippedAddress.getHostAddress}")
-          return strippedAddress
-        }
-      }
-      warn(s"${address.getHostName} was resolved to a loopback address: 
${address.getHostAddress}" +
-        " but we couldn't find any external IP address!")
-    }
-    address
-  }
-
   /**
    * return date of format yyyyMMdd
    */
diff --git 
a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/TFrontendService.scala 
b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/TFrontendService.scala
index 40e44ac40..801236f66 100644
--- 
a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/TFrontendService.scala
+++ 
b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/TFrontendService.scala
@@ -25,7 +25,7 @@ import scala.language.implicitConversions
 
 import org.apache.hadoop.conf.Configuration
 
-import org.apache.kyuubi.{KyuubiSQLException, Logging, Utils}
+import org.apache.kyuubi.{KyuubiSQLException, Logging}
 import org.apache.kyuubi.Utils.stringifyException
 import org.apache.kyuubi.config.KyuubiConf.{FRONTEND_ADVERTISED_HOST, 
FRONTEND_CONNECTION_URL_USE_HOSTNAME, PROXY_USER, SESSION_CLOSE_ON_DISCONNECT}
 import org.apache.kyuubi.config.KyuubiReservedKeys._
@@ -36,7 +36,7 @@ import org.apache.kyuubi.shaded.hive.service.rpc.thrift._
 import org.apache.kyuubi.shaded.thrift.protocol.TProtocol
 import org.apache.kyuubi.shaded.thrift.server.{ServerContext, 
TServerEventHandler}
 import org.apache.kyuubi.shaded.thrift.transport.TTransport
-import org.apache.kyuubi.util.{KyuubiHadoopUtils, NamedThreadFactory}
+import org.apache.kyuubi.util.{JavaUtils, KyuubiHadoopUtils, 
NamedThreadFactory}
 
 /**
  * Apache Thrift based hive-service-rpc base class
@@ -53,7 +53,7 @@ abstract class TFrontendService(name: String)
   protected def serverHost: Option[String]
   protected def portNum: Int
   protected lazy val serverAddr: InetAddress =
-    serverHost.map(InetAddress.getByName).getOrElse(Utils.findLocalInetAddress)
+    
serverHost.map(InetAddress.getByName).getOrElse(JavaUtils.findLocalInetAddress)
   protected lazy val serverSocket = new ServerSocket(portNum, -1, serverAddr)
   protected lazy val actualPort: Int = serverSocket.getLocalPort
   protected lazy val authFactory: KyuubiAuthenticationFactory =
diff --git a/kyuubi-common/src/test/scala/org/apache/kyuubi/UtilsSuite.scala 
b/kyuubi-common/src/test/scala/org/apache/kyuubi/UtilsSuite.scala
index 60bdd3d22..15776f8ac 100644
--- a/kyuubi-common/src/test/scala/org/apache/kyuubi/UtilsSuite.scala
+++ b/kyuubi-common/src/test/scala/org/apache/kyuubi/UtilsSuite.scala
@@ -18,7 +18,6 @@
 package org.apache.kyuubi
 
 import java.io.{File, IOException}
-import java.net.InetAddress
 import java.nio.file.{Files, Paths}
 import java.security.PrivilegedExceptionAction
 import java.util.Properties
@@ -118,15 +117,6 @@ class UtilsSuite extends KyuubiFunSuite {
       })
   }
 
-  test("findLocalInetAddress") {
-    val address = InetAddress.getLocalHost
-    if (!address.isLoopbackAddress) {
-      assert(Utils.findLocalInetAddress === InetAddress.getLocalHost)
-    } else {
-      assert(Utils.findLocalInetAddress !== InetAddress.getLocalHost)
-    }
-  }
-
   test("getAbsolutePathFromWork") {
     val workDir = System.getenv("KYUUBI_WORK_DIR_ROOT")
     val path1 = "path1"
diff --git 
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java
 
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java
index de5e27a7a..596f52cba 100644
--- 
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java
+++ 
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java
@@ -25,6 +25,7 @@ import java.util.Map.Entry;
 import java.util.Properties;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
+import org.apache.kyuubi.util.JavaUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,7 +41,7 @@ public class UserHS2ConnectionFileParser implements 
HS2ConnectionFileParser {
   public static final String DEFAULT_BEELINE_USER_CONF_LOCATION =
       System.getProperty("user.home")
           + File.separator
-          + (System.getProperty("os.name").toLowerCase().indexOf("windows") != 
-1 ? "" : ".")
+          + (JavaUtils.isWindows ? "" : ".")
           + "beeline"
           + File.separator;
   public static final String ETC_HIVE_CONF_LOCATION =
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/engine/spark/SparkProcessBuilder.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/engine/spark/SparkProcessBuilder.scala
index fcf24b930..aacdddef3 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/engine/spark/SparkProcessBuilder.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/engine/spark/SparkProcessBuilder.scala
@@ -37,7 +37,7 @@ import org.apache.kyuubi.ha.HighAvailabilityConf
 import org.apache.kyuubi.ha.HighAvailabilityConf.HA_ZK_ENGINE_AUTH_TYPE
 import org.apache.kyuubi.ha.client.AuthTypes
 import org.apache.kyuubi.operation.log.OperationLog
-import org.apache.kyuubi.util.{KubernetesUtils, Validator}
+import org.apache.kyuubi.util.{JavaUtils, KubernetesUtils, Validator}
 import org.apache.kyuubi.util.command.CommandLineUtils._
 
 class SparkProcessBuilder(
@@ -359,7 +359,8 @@ object SparkProcessBuilder {
   final private[spark] val PRINCIPAL = "spark.kerberos.principal"
   final private[spark] val KEYTAB = "spark.kerberos.keytab"
   // Get the appropriate spark-submit file
-  final private val SPARK_SUBMIT_FILE = if (Utils.isWindows) 
"spark-submit.cmd" else "spark-submit"
+  final private val SPARK_SUBMIT_FILE =
+    if (JavaUtils.isWindows) "spark-submit.cmd" else "spark-submit"
   final private val SPARK_CONF_DIR = "SPARK_CONF_DIR"
   final private val SPARK_CONF_FILE_NAME = "spark-defaults.conf"
 
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiMySQLFrontendService.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiMySQLFrontendService.scala
index 1a449dde4..447991ebc 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiMySQLFrontendService.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiMySQLFrontendService.scala
@@ -33,7 +33,7 @@ import org.apache.kyuubi.server.mysql._
 import org.apache.kyuubi.server.mysql.NettyUtils._
 import org.apache.kyuubi.server.mysql.authentication.MySQLAuthHandler
 import org.apache.kyuubi.service.{AbstractFrontendService, Serverable, Service}
-import org.apache.kyuubi.util.NamedThreadFactory
+import org.apache.kyuubi.util.{JavaUtils, NamedThreadFactory}
 
 /**
  * A frontend service implement MySQL protocol.
@@ -64,7 +64,7 @@ class KyuubiMySQLFrontendService(override val serverable: 
Serverable)
 
     serverAddr = conf.get(FRONTEND_MYSQL_BIND_HOST)
       .map(InetAddress.getByName)
-      .getOrElse(Utils.findLocalInetAddress)
+      .getOrElse(JavaUtils.findLocalInetAddress)
     port = conf.get(FRONTEND_MYSQL_BIND_PORT)
     val workerThreads = 
defaultNumThreads(conf.get(FRONTEND_MYSQL_NETTY_WORKER_THREADS))
     val bossGroup = createEventLoop(1, "mysql-netty-boss")
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
index 06eb63fee..811f3d053 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
@@ -37,7 +37,7 @@ import org.apache.kyuubi.server.ui.{JettyServer, JettyUtils}
 import org.apache.kyuubi.service.{AbstractFrontendService, Serverable, 
Service, ServiceUtils}
 import org.apache.kyuubi.service.authentication.{AuthTypes, AuthUtils}
 import org.apache.kyuubi.session.{KyuubiSessionManager, SessionHandle}
-import org.apache.kyuubi.util.ThreadUtils
+import org.apache.kyuubi.util.{JavaUtils, ThreadUtils}
 import 
org.apache.kyuubi.util.ThreadUtils.scheduleTolerableRunnableWithFixedDelay
 
 /**
@@ -59,13 +59,13 @@ class KyuubiRestFrontendService(override val serverable: 
Serverable)
 
   lazy val host: String = conf.get(FRONTEND_REST_BIND_HOST)
     .getOrElse {
-      if (Utils.isWindows || Utils.isMac) {
+      if (JavaUtils.isWindows || JavaUtils.isMac) {
         warn(s"Kyuubi Server run in Windows or Mac environment, binding 
$getName to 0.0.0.0")
         "0.0.0.0"
       } else if (conf.get(KyuubiConf.FRONTEND_CONNECTION_URL_USE_HOSTNAME)) {
-        Utils.findLocalInetAddress.getCanonicalHostName
+        JavaUtils.findLocalInetAddress.getCanonicalHostName
       } else {
-        Utils.findLocalInetAddress.getHostAddress
+        JavaUtils.findLocalInetAddress.getHostAddress
       }
     }
 
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiTrinoFrontendService.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiTrinoFrontendService.scala
index bef0b6f93..781f7e615 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiTrinoFrontendService.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiTrinoFrontendService.scala
@@ -19,12 +19,13 @@ package org.apache.kyuubi.server
 
 import java.util.concurrent.atomic.AtomicBoolean
 
-import org.apache.kyuubi.{KyuubiException, Utils}
+import org.apache.kyuubi.KyuubiException
 import org.apache.kyuubi.config.KyuubiConf
-import org.apache.kyuubi.config.KyuubiConf.{FRONTEND_ADVERTISED_HOST, 
FRONTEND_TRINO_BIND_HOST, FRONTEND_TRINO_BIND_PORT, 
FRONTEND_TRINO_JETTY_STOP_TIMEOUT, FRONTEND_TRINO_MAX_WORKER_THREADS}
+import org.apache.kyuubi.config.KyuubiConf._
 import org.apache.kyuubi.server.trino.api.v1.ApiRootResource
 import org.apache.kyuubi.server.ui.JettyServer
 import org.apache.kyuubi.service.{AbstractFrontendService, Serverable, Service}
+import org.apache.kyuubi.util.JavaUtils
 
 /**
  * A frontend service based on RESTful api via HTTP protocol.
@@ -40,9 +41,9 @@ class KyuubiTrinoFrontendService(override val serverable: 
Serverable)
   lazy val host: String = conf.get(FRONTEND_TRINO_BIND_HOST)
     .getOrElse {
       if (conf.get(KyuubiConf.FRONTEND_CONNECTION_URL_USE_HOSTNAME)) {
-        Utils.findLocalInetAddress.getCanonicalHostName
+        JavaUtils.findLocalInetAddress.getCanonicalHostName
       } else {
-        Utils.findLocalInetAddress.getHostAddress
+        JavaUtils.findLocalInetAddress.getHostAddress
       }
     }
 
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/ui/JettyServer.scala 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/ui/JettyServer.scala
index 7f4043534..f0b752061 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/ui/JettyServer.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/ui/JettyServer.scala
@@ -22,7 +22,7 @@ import 
org.eclipse.jetty.server.handler.{ContextHandlerCollection, ErrorHandler}
 import org.eclipse.jetty.util.component.LifeCycle
 import org.eclipse.jetty.util.thread.{QueuedThreadPool, 
ScheduledExecutorScheduler}
 
-import org.apache.kyuubi.Utils.isWindows
+import org.apache.kyuubi.util.JavaUtils
 
 private[kyuubi] case class JettyServer(
     server: Server,
@@ -105,7 +105,7 @@ object JettyServer {
       new HttpConnectionFactory(httpConf))
     connector.setHost(host)
     connector.setPort(port)
-    connector.setReuseAddress(!isWindows)
+    connector.setReuseAddress(!JavaUtils.isWindows)
     connector.setAcceptQueueSize(math.min(connector.getAcceptors, 8))
 
     new JettyServer(server, connector, collection)
diff --git a/kyuubi-util/pom.xml b/kyuubi-util/pom.xml
index dc695d360..fcb3498b1 100644
--- a/kyuubi-util/pom.xml
+++ b/kyuubi-util/pom.xml
@@ -36,6 +36,11 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java 
b/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java
index 210c1b93c..eafad685e 100644
--- a/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java
+++ b/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java
@@ -20,10 +20,23 @@
 package org.apache.kyuubi.util;
 
 import java.io.File;
-import java.net.URISyntaxException;
+import java.net.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class JavaUtils {
 
+  private static final Logger LOG = LoggerFactory.getLogger(JavaUtils.class);
+
+  /** Whether the underlying operating system is Windows. */
+  public static final boolean isWindows = System.getProperty("os.name", 
"").startsWith("Windows");
+
+  /** Whether the underlying operating system is MacOS. */
+  public static final boolean isMac = System.getProperty("os.name", 
"").startsWith("Mac");
+
   public static String getCodeSourceLocation(Class<?> clazz) {
     try {
       return new 
File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath();
@@ -31,4 +44,46 @@ public class JavaUtils {
       throw new RuntimeException(rethrow);
     }
   }
+
+  public static InetAddress findLocalInetAddress() throws 
UnknownHostException, SocketException {
+    InetAddress address = InetAddress.getLocalHost();
+    if (address.isLoopbackAddress()) {
+      List<NetworkInterface> activeNetworkIFs =
+          Collections.list(NetworkInterface.getNetworkInterfaces());
+      if (!isWindows) {
+        Collections.reverse(activeNetworkIFs);
+      }
+
+      for (NetworkInterface ni : activeNetworkIFs) {
+        List<InetAddress> addresses =
+            Collections.list(ni.getInetAddresses()).stream()
+                .filter(addr -> !addr.isLinkLocalAddress() && 
!addr.isLoopbackAddress())
+                .collect(Collectors.toList());
+
+        if (!addresses.isEmpty()) {
+          InetAddress addr =
+              addresses.stream()
+                  .filter(a -> a instanceof Inet4Address)
+                  .findFirst()
+                  .orElse(addresses.get(0));
+
+          InetAddress strippedAddress = 
InetAddress.getByAddress(addr.getAddress());
+
+          // We've found an address that looks reasonable!
+          LOG.warn(
+              "{} was resolved to a loopback address: {}, using {}",
+              addr.getHostName(),
+              addr.getHostAddress(),
+              strippedAddress.getHostAddress());
+          return strippedAddress;
+        }
+      }
+
+      LOG.warn(
+          "{} was resolved to a loopback address: {} but we couldn't find any 
external IP address!",
+          address.getHostName(),
+          address.getHostAddress());
+    }
+    return address;
+  }
 }
diff --git a/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java 
b/kyuubi-util/src/test/java/org/apache/kyuubi/util/JavaUtilsTest.java
similarity index 58%
copy from kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java
copy to kyuubi-util/src/test/java/org/apache/kyuubi/util/JavaUtilsTest.java
index 210c1b93c..9bcb3253d 100644
--- a/kyuubi-util/src/main/java/org/apache/kyuubi/util/JavaUtils.java
+++ b/kyuubi-util/src/test/java/org/apache/kyuubi/util/JavaUtilsTest.java
@@ -19,16 +19,23 @@
 
 package org.apache.kyuubi.util;
 
-import java.io.File;
-import java.net.URISyntaxException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
-public class JavaUtils {
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import org.junit.Test;
 
-  public static String getCodeSourceLocation(Class<?> clazz) {
-    try {
-      return new 
File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath();
-    } catch (URISyntaxException rethrow) {
-      throw new RuntimeException(rethrow);
+public class JavaUtilsTest {
+
+  @Test
+  public void testFindLocalInetAddress() throws UnknownHostException, 
SocketException {
+    InetAddress address = InetAddress.getLocalHost();
+    if (!address.isLoopbackAddress()) {
+      assertEquals(InetAddress.getLocalHost(), 
JavaUtils.findLocalInetAddress());
+    } else {
+      assertNotEquals(InetAddress.getLocalHost(), 
JavaUtils.findLocalInetAddress());
     }
   }
 }
diff --git 
a/kyuubi-zookeeper/src/main/scala/org/apache/kyuubi/zookeeper/EmbeddedZookeeper.scala
 
b/kyuubi-zookeeper/src/main/scala/org/apache/kyuubi/zookeeper/EmbeddedZookeeper.scala
index 1592d9063..46a71286e 100644
--- 
a/kyuubi-zookeeper/src/main/scala/org/apache/kyuubi/zookeeper/EmbeddedZookeeper.scala
+++ 
b/kyuubi-zookeeper/src/main/scala/org/apache/kyuubi/zookeeper/EmbeddedZookeeper.scala
@@ -25,6 +25,7 @@ import org.apache.kyuubi.Utils._
 import org.apache.kyuubi.config.{ConfigEntry, KyuubiConf}
 import org.apache.kyuubi.service.{AbstractService, ServiceState}
 import org.apache.kyuubi.shaded.zookeeper.server.{NIOServerCnxnFactory, 
ZooKeeperServer}
+import org.apache.kyuubi.util.JavaUtils
 import org.apache.kyuubi.zookeeper.ZookeeperConf._
 
 class EmbeddedZookeeper extends AbstractService("EmbeddedZookeeper") {
@@ -48,9 +49,9 @@ class EmbeddedZookeeper extends 
AbstractService("EmbeddedZookeeper") {
     val maxSessionTimeout = conf.get(ZK_MAX_SESSION_TIMEOUT)
     host = conf.get(ZK_CLIENT_PORT_ADDRESS).getOrElse {
       if (conf.get(ZK_CLIENT_USE_HOSTNAME)) {
-        findLocalInetAddress.getCanonicalHostName
+        JavaUtils.findLocalInetAddress.getCanonicalHostName
       } else {
-        findLocalInetAddress.getHostAddress
+        JavaUtils.findLocalInetAddress.getHostAddress
       }
     }
 

Reply via email to