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

rong pushed a commit to branch test-4
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 053af93e1404d5fc661e775b4ed36f64fef1d403
Author: Steve Yurong Su <[email protected]>
AuthorDate: Fri Jun 20 11:28:21 2025 +0800

    move validation logic to ClusterConfigTaskExecutor.java
---
 .../iotdb/confignode/manager/UDFManager.java       | 38 ---------------------
 .../config/executor/ClusterConfigTaskExecutor.java | 39 ++++++++++++++++++----
 2 files changed, 32 insertions(+), 45 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/UDFManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/UDFManager.java
index 59be1fd5a4f..00ed020a14e 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/UDFManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/UDFManager.java
@@ -23,8 +23,6 @@ import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.udf.UDFInformation;
-import org.apache.iotdb.commons.udf.service.UDFClassLoader;
-import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
 import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
 import 
org.apache.iotdb.confignode.client.async.CnToDnInternalServiceAsyncRequestManager;
 import 
org.apache.iotdb.confignode.client.async.handlers.DataNodeAsyncRequestContext;
@@ -45,7 +43,6 @@ import 
org.apache.iotdb.mpp.rpc.thrift.TCreateFunctionInstanceReq;
 import org.apache.iotdb.mpp.rpc.thrift.TDropFunctionInstanceReq;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
-import org.apache.iotdb.udf.api.UDF;
 
 import org.apache.tsfile.utils.Binary;
 import org.slf4j.Logger;
@@ -92,13 +89,6 @@ public class UDFManager {
           new UDFInformation(udfName, req.getClassName(), false, isUsingURI, 
jarName, jarMD5);
       final boolean needToSaveJar = isUsingURI && 
udfInfo.needToSaveJar(jarName);
 
-      final TSStatus status = 
sandboxValidationBeforeCreateFunction(udfInformation);
-      if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-        LOGGER.warn(
-            "Sandbox validation failed for UDF [{}], reason: {}", udfName, 
status.getMessage());
-        return status;
-      }
-
       LOGGER.info(
           "Start to create UDF [{}] on Data Nodes, needToSaveJar[{}]", 
udfName, needToSaveJar);
 
@@ -131,34 +121,6 @@ public class UDFManager {
     }
   }
 
-  private TSStatus sandboxValidationBeforeCreateFunction(final UDFInformation 
udfInformation) {
-    try (final UDFClassLoader classLoader =
-        new UDFClassLoader(UDFExecutableManager.getInstance().getLibRoot())) {
-      // ensure that jar file contains the class and the class is a UDF
-      final Class<?> clazz = Class.forName(udfInformation.getClassName(), 
true, classLoader);
-      final UDF udf = (UDF) clazz.getDeclaredConstructor().newInstance();
-      return udf.validate()
-          .map(
-              e ->
-                  RpcUtils.getStatus(
-                      TSStatusCode.UDF_LOAD_CLASS_ERROR,
-                      String.format(
-                          "Fail to validate UDF class [%s] for function [%s] 
in sandbox, reason: %s",
-                          udfInformation.getClassName(),
-                          udfInformation.getFunctionName(),
-                          e.getMessage())))
-          .orElse(RpcUtils.SUCCESS_STATUS);
-    } catch (final Throwable throwable) {
-      return RpcUtils.getStatus(
-          TSStatusCode.UDF_LOAD_CLASS_ERROR,
-          String.format(
-              "Fail to reflect or validate UDF class [%s] for function [%s] in 
sandbox, reason: %s",
-              udfInformation.getClassName(),
-              udfInformation.getFunctionName(),
-              throwable.getMessage()));
-    }
-  }
-
   private List<TSStatus> createFunctionOnDataNodes(UDFInformation 
udfInformation, byte[] jarFile)
       throws IOException {
     final Map<Integer, TDataNodeLocation> dataNodeLocationMap =
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index d2b5d0bbe77..4f4e7c7a27f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -536,12 +536,37 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
         // ensure that jar file contains the class and the class is a UDF
         Class<?> clazz = Class.forName(createFunctionStatement.getClassName(), 
true, classLoader);
         UDF udf = (UDF) clazz.getDeclaredConstructor().newInstance();
-      } catch (ClassNotFoundException
-          | NoSuchMethodException
-          | InstantiationException
-          | IllegalAccessException
-          | InvocationTargetException
-          | ClassCastException e) {
+
+        final TSStatus maybeValidationFailed =
+            udf.validate()
+                .map(
+                    e ->
+                        RpcUtils.getStatus(
+                            TSStatusCode.UDF_LOAD_CLASS_ERROR,
+                            String.format(
+                                "Fail to validate UDF class [%s] for function 
[%s] in sandbox, reason: %s",
+                                createFunctionStatement.getClassName(),
+                                createFunctionStatement.getUdfName(),
+                                e.getMessage())))
+                .orElse(RpcUtils.SUCCESS_STATUS);
+        if (maybeValidationFailed.getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+          LOGGER.warn(
+              "Failed to validate UDF class [{}] for function [{}] in sandbox, 
reason: {}",
+              createFunctionStatement.getClassName(),
+              createFunctionStatement.getUdfName(),
+              maybeValidationFailed.getMessage());
+          future.setException(
+              new IoTDBException(
+                  "Failed to validate UDF class '"
+                      + createFunctionStatement.getClassName()
+                      + "' for function '"
+                      + createFunctionStatement.getUdfName()
+                      + "', reason: "
+                      + maybeValidationFailed.getMessage(),
+                  maybeValidationFailed.getCode()));
+          return future;
+        }
+      } catch (Exception e) {
         LOGGER.warn(
             "Failed to create function when try to create UDF({}) instance 
first.",
             createFunctionStatement.getUdfName(),
@@ -567,7 +592,7 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
       } else {
         future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
       }
-    } catch (ClientManagerException | IOException | TException e) {
+    } catch (Exception e) {
       future.setException(e);
     }
     return future;

Reply via email to