From 28cadbc3d02e93b37e4662583503e3193a2e45c4 Mon Sep 17 00:00:00 2001 From: Hoon Oh Date: Thu, 16 Apr 2026 12:14:13 -0400 Subject: [PATCH 1/5] STGroup free to avoid OOM Kill --- .../apache/kyuubi/service/authentication/ldap/Query.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala index ce9a7d47214..e23fff65317 100644 --- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala +++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala @@ -20,7 +20,7 @@ package org.apache.kyuubi.service.authentication.ldap import java.util import javax.naming.directory.SearchControls -import org.stringtemplate.v4.ST +import org.stringtemplate.v4.{ST, STGroup} /** * The object that encompasses all components of a Directory Service search query. @@ -56,7 +56,8 @@ object Query { * @return the current instance of the builder */ def filter(filterTemplate: String): Query.QueryBuilder = { - this.filterTemplate = new ST(filterTemplate) + val group = new STGroup() + this.filterTemplate = new ST(group, filterTemplate) this } @@ -127,6 +128,8 @@ object Query { def build: Query = { validate() val filter: String = createFilter + // Unload template cache after render to avoid CompliedST/STToken retntion + Option(filterTemplate.groupThatCreatedThisInstance).foreach(_.unload()) updateControls() new Query(filter, controls) } From 321c4306db6ffda0c017d772f8c230f7f2e70eb4 Mon Sep 17 00:00:00 2001 From: Hoon Oh <92890928+oh0873@users.noreply.github.com> Date: Mon, 20 Apr 2026 10:39:13 -0400 Subject: [PATCH 2/5] Update kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala Spelling Fix Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../org/apache/kyuubi/service/authentication/ldap/Query.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala index e23fff65317..365d75050b7 100644 --- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala +++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala @@ -128,7 +128,7 @@ object Query { def build: Query = { validate() val filter: String = createFilter - // Unload template cache after render to avoid CompliedST/STToken retntion + // Unload template cache after render to avoid CompiledST/STToken retention Option(filterTemplate.groupThatCreatedThisInstance).foreach(_.unload()) updateControls() new Query(filter, controls) From dd0f9103d0c6621a13690d77b5f129957574f62b Mon Sep 17 00:00:00 2001 From: Hoon Oh Date: Mon, 20 Apr 2026 10:56:11 -0400 Subject: [PATCH 3/5] Explicit group definition --- .../apache/kyuubi/service/authentication/ldap/Query.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala index 365d75050b7..b456969c8df 100644 --- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala +++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala @@ -40,6 +40,8 @@ object Query { * A builder of the [[Query]]. */ final class QueryBuilder { + /** The [[STGroup]] used only for this builder's filter template; unloaded in [[build]]. */ + private var filterTemplateGroup: Option[STGroup] = None private var filterTemplate: ST = _ private val controls: SearchControls = { val _controls = new SearchControls @@ -57,6 +59,7 @@ object Query { */ def filter(filterTemplate: String): Query.QueryBuilder = { val group = new STGroup() + this.filterTemplateGroup = Some(group) this.filterTemplate = new ST(group, filterTemplate) this } @@ -129,7 +132,7 @@ object Query { validate() val filter: String = createFilter // Unload template cache after render to avoid CompiledST/STToken retention - Option(filterTemplate.groupThatCreatedThisInstance).foreach(_.unload()) + filterTemplateGroup.foreach(_.unload()) updateControls() new Query(filter, controls) } From 18ee9bb66c3701fb41596f30e9eb2978d3cbe125 Mon Sep 17 00:00:00 2001 From: Hoon Oh Date: Tue, 21 Apr 2026 13:38:53 -0400 Subject: [PATCH 4/5] Added () to createFilter and render --- .../apache/kyuubi/service/authentication/ldap/Query.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala index b456969c8df..a33456a7d2e 100644 --- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala +++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala @@ -40,6 +40,7 @@ object Query { * A builder of the [[Query]]. */ final class QueryBuilder { + /** The [[STGroup]] used only for this builder's filter template; unloaded in [[build]]. */ private var filterTemplateGroup: Option[STGroup] = None private var filterTemplate: ST = _ @@ -116,7 +117,7 @@ object Query { require(filterTemplate != null, "filter is required for LDAP search query") } - private def createFilter: String = filterTemplate.render + private def createFilter(): String = filterTemplate.render() private def updateControls(): Unit = { if (!returningAttributes.isEmpty) controls.setReturningAttributes( @@ -130,7 +131,7 @@ object Query { */ def build: Query = { validate() - val filter: String = createFilter + val filter: String = createFilter() // Unload template cache after render to avoid CompiledST/STToken retention filterTemplateGroup.foreach(_.unload()) updateControls() From 72740e0e0135250c60d0f046dd9765da85ea9385 Mon Sep 17 00:00:00 2001 From: Hoon Oh <92890928+oh0873@users.noreply.github.com> Date: Mon, 27 Apr 2026 14:15:04 -0400 Subject: [PATCH 5/5] Update kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala Co-authored-by: Cheng Pan --- .../org/apache/kyuubi/service/authentication/ldap/Query.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala index a33456a7d2e..3c0321c748c 100644 --- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala +++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/Query.scala @@ -25,6 +25,9 @@ import org.stringtemplate.v4.{ST, STGroup} /** * The object that encompasses all components of a Directory Service search query. * + * The caller must and can only call each [[filter]] and [[build]] once, + * otherwise [[ST]] internal cache may leak and cause heap OOM. + * * @see [[LdapSearch]] */ object Query {