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..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 @@ -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. @@ -40,6 +40,9 @@ 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 @@ -56,7 +59,9 @@ 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.filterTemplateGroup = Some(group) + this.filterTemplate = new ST(group, filterTemplate) this } @@ -112,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( @@ -126,7 +131,9 @@ 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() new Query(filter, controls) }