You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by dw...@apache.org on 2020/01/20 15:52:20 UTC

[flink] branch release-1.10 updated: [FLINK-15599][table] SQL client requires both legacy and blink planner to be on the classpath

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

dwysakowicz pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git


The following commit(s) were added to refs/heads/release-1.10 by this push:
     new ca1cacd  [FLINK-15599][table] SQL client requires both legacy and blink planner to be on the classpath
ca1cacd is described below

commit ca1cacd3494232bb7f34327c829033160a86abcd
Author: JingsongLi <lz...@aliyun.com>
AuthorDate: Fri Jan 17 14:16:31 2020 +0800

    [FLINK-15599][table] SQL client requires both legacy and blink planner to be on the classpath
    
    This closes #10878
---
 .../client/gateway/local/ExecutionContext.java     |  26 ++-
 .../table/client/gateway/local/LocalExecutor.java  |   4 +-
 .../flink/table/functions/FunctionService.java     | 186 +++++++++++++++++++++
 .../flink/table/functions/FunctionServiceTest.java | 172 +++++++++++++++++++
 .../planner/delegation/BlinkPlannerFactory.java    |   1 +
 .../flink/table/planner/StreamPlannerFactory.java  |   1 +
 .../flink/table/functions/FunctionService.scala    | 160 ------------------
 .../table/functions/FunctionServiceTest.scala      | 125 --------------
 8 files changed, 372 insertions(+), 303 deletions(-)

diff --git a/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/ExecutionContext.java b/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/ExecutionContext.java
index 8a1f082..174c014 100644
--- a/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/ExecutionContext.java
+++ b/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/ExecutionContext.java
@@ -265,20 +265,27 @@ public class ExecutionContext<ClusterID> {
 		}
 	}
 
-	public Pipeline createPipeline(String name, Configuration flinkConfig) {
+	public Pipeline createPipeline(String name) {
 		if (streamExecEnv != null) {
 			// special case for Blink planner to apply batch optimizations
 			// note: it also modifies the ExecutionConfig!
-			if (executor instanceof ExecutorBase) {
+			if (isBlinkPlanner(executor.getClass())) {
 				return ((ExecutorBase) executor).getStreamGraph(name);
 			}
 			return streamExecEnv.getStreamGraph(name);
 		} else {
-			final int parallelism = execEnv.getParallelism();
 			return execEnv.createProgramPlan(name);
 		}
 	}
 
+	private boolean isBlinkPlanner(Class<? extends Executor> executorClass) {
+		try {
+			return ExecutorBase.class.isAssignableFrom(executorClass);
+		} catch (NoClassDefFoundError ignore) {
+			// blink planner might not be on the class path
+			return false;
+		}
+	}
 
 	/** Returns a builder for this {@link ExecutionContext}. */
 	public static Builder builder(
@@ -682,19 +689,6 @@ public class ExecutionContext<ClusterID> {
 		}
 	}
 
-	private Pipeline createPipeline(String name) {
-		if (streamExecEnv != null) {
-			// special case for Blink planner to apply batch optimizations
-			// note: it also modifies the ExecutionConfig!
-			if (executor instanceof ExecutorBase) {
-				return ((ExecutorBase) executor).getStreamGraph(name);
-			}
-			return streamExecEnv.getStreamGraph(name);
-		} else {
-			return execEnv.createProgramPlan(name);
-		}
-	}
-
 	//~ Inner Class -------------------------------------------------------------------------------
 
 	/** Builder for {@link ExecutionContext}. */
diff --git a/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/LocalExecutor.java b/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/LocalExecutor.java
index 513e215..d0846e2 100644
--- a/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/LocalExecutor.java
+++ b/flink-table/flink-sql-client/src/main/java/org/apache/flink/table/client/gateway/local/LocalExecutor.java
@@ -584,7 +584,7 @@ public class LocalExecutor implements Executor {
 		final String jobName = sessionId + ": " + statement;
 		final Pipeline pipeline;
 		try {
-			pipeline = context.createPipeline(jobName, context.getFlinkConfig());
+			pipeline = context.createPipeline(jobName);
 		} catch (Throwable t) {
 			// catch everything such that the statement does not crash the executor
 			throw new SqlExecutionException("Invalid SQL statement.", t);
@@ -628,7 +628,7 @@ public class LocalExecutor implements Executor {
 						context.getQueryConfig(),
 						tableName);
 			});
-			pipeline = context.createPipeline(jobName, context.getFlinkConfig());
+			pipeline = context.createPipeline(jobName);
 		} catch (Throwable t) {
 			// the result needs to be closed as long as
 			// it not stored in the result store
diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/FunctionService.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/FunctionService.java
new file mode 100644
index 0000000..fb4a7d4
--- /dev/null
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/FunctionService.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.functions;
+
+import org.apache.flink.table.api.ValidationException;
+import org.apache.flink.table.descriptors.ClassInstanceValidator;
+import org.apache.flink.table.descriptors.DescriptorProperties;
+import org.apache.flink.table.descriptors.FunctionDescriptor;
+import org.apache.flink.table.descriptors.FunctionDescriptorValidator;
+import org.apache.flink.table.descriptors.HierarchyDescriptorValidator;
+import org.apache.flink.table.descriptors.LiteralValueValidator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service for creating configured instances of {@link UserDefinedFunction} using a
+ * {@link FunctionDescriptor}.
+ */
+public class FunctionService {
+
+	private static final Logger LOG = LoggerFactory.getLogger(FunctionService.class);
+
+	/**
+	 * Creates a user-defined function with the given properties and the current thread's
+	 * context class loader.
+	 *
+	 * @param descriptor the descriptor that describes a function
+	 * @return the generated user-defined function
+	 */
+	public static UserDefinedFunction createFunction(FunctionDescriptor descriptor) {
+		return createFunction(descriptor, Thread.currentThread().getContextClassLoader());
+	}
+
+	/**
+	 * Creates a user-defined function with the given properties.
+	 *
+	 * @param descriptor the descriptor that describes a function
+	 * @param classLoader the class loader to load the function and its parameter's classes
+	 * @return the generated user-defined function
+	 */
+	public static UserDefinedFunction createFunction(
+			FunctionDescriptor descriptor,
+			ClassLoader classLoader) {
+		return createFunction(descriptor, classLoader, true);
+	}
+
+	/**
+	 * Creates a user-defined function with the given properties.
+	 *
+	 * @param descriptor the descriptor that describes a function
+	 * @param classLoader the class loader to load the function and its parameter's classes
+	 * @param performValidation whether or not the descriptor should be validated
+	 * @return the generated user-defined function
+	 */
+	public static UserDefinedFunction createFunction(
+			FunctionDescriptor descriptor,
+			ClassLoader classLoader,
+			boolean performValidation) {
+
+		DescriptorProperties properties = new DescriptorProperties(true);
+		properties.putProperties(descriptor.toProperties());
+
+		// validate
+		if (performValidation) {
+			new FunctionDescriptorValidator().validate(properties);
+		}
+
+		// instantiate
+		Object instance = generateInstance(
+				HierarchyDescriptorValidator.EMPTY_PREFIX,
+				properties,
+				classLoader);
+
+		if (!UserDefinedFunction.class.isAssignableFrom(instance.getClass())) {
+			throw new ValidationException(String.format(
+					"Instantiated class '%s' is not a user-defined function.",
+					instance.getClass().getName()));
+		}
+		return (UserDefinedFunction) instance;
+	}
+
+	/**
+	 * Recursively generate an instance of a class according the given properties.
+	 *
+	 * @param keyPrefix the prefix to fetch properties
+	 * @param descriptorProperties the descriptor properties that contains the class type information
+	 * @param classLoader the class loader to load the class
+	 * @param <T> type fo the generated instance
+	 * @return an instance of the class
+	 */
+	private static <T> T generateInstance(
+			String keyPrefix,
+			DescriptorProperties descriptorProperties,
+			ClassLoader classLoader) {
+		String instanceClassName = descriptorProperties.getString(
+				keyPrefix + ClassInstanceValidator.CLASS);
+
+		Class<T> instanceClass;
+		try {
+			//noinspection unchecked
+			instanceClass = (Class<T>) Class.forName(instanceClassName, true, classLoader);
+		} catch (Exception e) {
+			// only log the cause to have clean error messages
+			String msg = String.format(
+					"Could not find class '%s' for creating an instance.", instanceClassName);
+			LOG.error(msg, e);
+			throw new ValidationException(msg);
+		}
+
+		String constructorPrefix = keyPrefix + ClassInstanceValidator.CONSTRUCTOR;
+
+		List<Map<String, String>> constructorProps = descriptorProperties
+				.getVariableIndexedProperties(constructorPrefix, new ArrayList<>());
+
+		ArrayList<Object> parameterList = new ArrayList<>();
+		for (int i = 0; i < constructorProps.size(); i++) {
+			String constructorKey = constructorPrefix + "." + i + ".";
+			// nested class instance
+			if (constructorProps.get(i).containsKey(ClassInstanceValidator.CLASS)) {
+				parameterList.add(generateInstance(
+						constructorKey,
+						descriptorProperties,
+						classLoader));
+			}
+			// literal value
+			else {
+				Object literalValue = LiteralValueValidator.getValue(
+						constructorKey, descriptorProperties);
+				parameterList.add(literalValue);
+			}
+		}
+
+		String parameterNames = parameterList.stream()
+				.map(t -> t.getClass().getName())
+				.reduce((s1, s2) -> s1 + ", " + s2)
+				.orElse("");
+
+		Constructor<T> constructor;
+		try {
+			constructor = instanceClass.getConstructor(
+					parameterList.stream().map(Object::getClass).toArray(Class[]::new));
+		} catch (Exception e) {
+			// only log the cause to have clean error messages
+			String msg = String.format(
+					"Cannot find a public constructor with parameter types '%s' for '%s'.",
+					parameterNames,
+					instanceClassName);
+			LOG.error(msg, e);
+			throw new ValidationException(msg);
+		}
+
+		try {
+			return constructor.newInstance(parameterList.toArray());
+		} catch (Exception e) {
+			// only log the cause to have clean error messages
+			String msg = String.format(
+					"Error while creating instance of class '%s' with parameter types '%s'.",
+					instanceClassName,
+					parameterNames);
+			LOG.error(msg, e);
+			throw new ValidationException(msg);
+		}
+	}
+}
diff --git a/flink-table/flink-table-common/src/test/java/org/apache/flink/table/functions/FunctionServiceTest.java b/flink-table/flink-table-common/src/test/java/org/apache/flink/table/functions/FunctionServiceTest.java
new file mode 100644
index 0000000..ea4030b
--- /dev/null
+++ b/flink-table/flink-table-common/src/test/java/org/apache/flink/table/functions/FunctionServiceTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.functions;
+
+import org.apache.flink.table.api.ValidationException;
+import org.apache.flink.table.descriptors.ClassInstance;
+import org.apache.flink.table.descriptors.FunctionDescriptor;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Tests for {@link FunctionService}.
+ */
+public class FunctionServiceTest {
+
+	@Test(expected = ValidationException.class)
+	public void testWrongArgsFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance()
+						.of(NoArgClass.class.getName())
+						.parameterString("12"));
+
+		FunctionService.createFunction(descriptor);
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testPrivateFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance().of(PrivateClass.class.getName()));
+
+		FunctionService.createFunction(descriptor);
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testInvalidClassFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance().of("this.class.does.not.exist"));
+
+		FunctionService.createFunction(descriptor);
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testNotFunctionClassFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance()
+						.of(String.class.getName())
+						.parameterString("hello"));
+
+		FunctionService.createFunction(descriptor);
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testErrorConstructorClass() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance()
+						.of(ErrorConstructorClass.class.getName())
+						.parameterString("arg"));
+
+		FunctionService.createFunction(descriptor);
+	}
+
+	@Test
+	public void testNoArgFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(new ClassInstance().of(NoArgClass.class.getName()));
+
+		assertEquals(NoArgClass.class, FunctionService.createFunction(descriptor).getClass());
+	}
+
+	@Test
+	public void testOneArgFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(
+						new ClassInstance()
+								.of(OneArgClass.class.getName())
+								.parameterString("false"));
+
+		UserDefinedFunction actualFunction = FunctionService.createFunction(descriptor);
+
+		assertEquals(OneArgClass.class, actualFunction.getClass());
+		assertFalse(((OneArgClass) actualFunction).field);
+	}
+
+	@Test
+	public void testMultiArgFunctionCreation() {
+		FunctionDescriptor descriptor = new FunctionDescriptor()
+				.fromClass(
+						new ClassInstance()
+								.of(MultiArgClass.class.getName())
+								.parameter(new java.math.BigDecimal("12.0003"))
+								.parameter(new ClassInstance()
+										.of(BigInteger.class.getName())
+										.parameter("111111111111111111111111111111111")));
+
+		UserDefinedFunction actualFunction = FunctionService.createFunction(descriptor);
+
+		assertEquals(MultiArgClass.class, actualFunction.getClass());
+		assertEquals(
+				new java.math.BigDecimal("12.0003"),
+				((MultiArgClass) actualFunction).field1);
+		assertEquals(
+				new java.math.BigInteger("111111111111111111111111111111111"),
+				((MultiArgClass) actualFunction).field2);
+	}
+
+	/**
+	 * Test no argument.
+	 */
+	public static class NoArgClass extends ScalarFunction {}
+
+	/**
+	 * Test one argument.
+	 */
+	public static class OneArgClass extends ScalarFunction {
+		public Boolean field;
+
+		public OneArgClass(Boolean field) {
+			this.field = field;
+		}
+	}
+
+	/**
+	 * Test multi arguments.
+	 */
+	public static class MultiArgClass extends ScalarFunction {
+		public final BigDecimal field1;
+		public final BigInteger field2;
+
+		public MultiArgClass(BigDecimal field1, BigInteger field2) {
+			this.field1 = field1;
+			this.field2 = field2;
+		}
+	}
+
+	/**
+	 * Test private constructor.
+	 */
+	public static class PrivateClass extends ScalarFunction {
+		private PrivateClass() {}
+	}
+
+	/**
+	 * Test error constructor.
+	 */
+	public static class ErrorConstructorClass extends ScalarFunction {
+		public ErrorConstructorClass(String arg) {
+			throw new RuntimeException(arg);
+		}
+	}
+}
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/planner/delegation/BlinkPlannerFactory.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/planner/delegation/BlinkPlannerFactory.java
index 87652b3..a9aeb14 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/planner/delegation/BlinkPlannerFactory.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/planner/delegation/BlinkPlannerFactory.java
@@ -53,6 +53,7 @@ public final class BlinkPlannerFactory implements PlannerFactory {
 		}
 	}
 
+	@Override
 	public Map<String, String> optionalContext() {
 		Map<String, String> map = new HashMap<>();
 		map.put(EnvironmentSettings.CLASS_NAME, this.getClass().getCanonicalName());
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/StreamPlannerFactory.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/StreamPlannerFactory.java
index 62e19bd..73868c1 100644
--- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/StreamPlannerFactory.java
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/StreamPlannerFactory.java
@@ -49,6 +49,7 @@ public final class StreamPlannerFactory implements PlannerFactory {
 		return new StreamPlanner(executor, tableConfig, functionCatalog, catalogManager);
 	}
 
+	@Override
 	public Map<String, String> optionalContext() {
 		Map<String, String> map = new HashMap<>();
 		map.put(EnvironmentSettings.CLASS_NAME, this.getClass().getCanonicalName());
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/functions/FunctionService.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/functions/FunctionService.scala
deleted file mode 100644
index acc1a1c..0000000
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/functions/FunctionService.scala
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions
-
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.descriptors._
-import org.apache.flink.table.util.Logging
-
-import scala.collection.JavaConversions._
-import scala.collection.mutable.ArrayBuffer
-
-/**
-  * Service for creating configured instances of [[UserDefinedFunction]] using a
-  * [[FunctionDescriptor]].
-  */
-object FunctionService extends Logging {
-
-  /**
-    * Creates a user-defined function with the given properties and the current thread's
-    * context class loader.
-    *
-    * @param descriptor the descriptor that describes a function
-    * @return the generated user-defined function
-    */
-  def createFunction(descriptor: FunctionDescriptor): UserDefinedFunction = {
-    createFunction(descriptor, Thread.currentThread().getContextClassLoader)
-  }
-
-  /**
-    * Creates a user-defined function with the given properties.
-    *
-    * @param descriptor the descriptor that describes a function
-    * @param classLoader the class loader to load the function and its parameter's classes
-    * @param performValidation whether or not the descriptor should be validated
-    * @return the generated user-defined function
-    */
-  def createFunction(
-      descriptor: FunctionDescriptor,
-      classLoader: ClassLoader,
-      performValidation: Boolean = true)
-    : UserDefinedFunction = {
-
-    val properties = new DescriptorProperties(true)
-    properties.putProperties(descriptor.toProperties)
-
-    // validate
-    if (performValidation) {
-      new FunctionDescriptorValidator().validate(properties)
-    }
-
-    // instantiate
-    val (instanceClass, instance) = generateInstance[AnyRef](
-      HierarchyDescriptorValidator.EMPTY_PREFIX,
-      properties,
-      classLoader)
-
-    if (!classOf[UserDefinedFunction].isAssignableFrom(instanceClass)) {
-      throw new ValidationException(
-        s"Instantiated class '${instanceClass.getName}' is not a user-defined function.")
-    }
-    instance.asInstanceOf[UserDefinedFunction]
-  }
-
-  /**
-   * Recursively generate an instance of a class according the given properties.
-   *
-   * @param keyPrefix the prefix to fetch properties
-   * @param descriptorProperties the descriptor properties that contains the class type information
-   * @param classLoader the class loader to load the class
-   * @tparam T type fo the generated instance
-   * @return an instance of the class
-   */
-  private def generateInstance[T](
-      keyPrefix: String,
-      descriptorProperties: DescriptorProperties,
-      classLoader: ClassLoader)
-    : (Class[T], T) = {
-
-    val instanceClassName = descriptorProperties.getString(
-      s"$keyPrefix${ClassInstanceValidator.CLASS}")
-
-    val instanceClass = try {
-      Class
-        .forName(
-          descriptorProperties.getString(s"$keyPrefix${ClassInstanceValidator.CLASS}"),
-          true,
-          classLoader)
-        .asInstanceOf[Class[T]]
-    } catch {
-      case e: Exception =>
-        // only log the cause to have clean error messages
-        val msg = s"Could not find class '$instanceClassName' for creating an instance."
-        LOG.error(msg, e)
-        throw new ValidationException(msg)
-    }
-
-    val constructorPrefix = s"$keyPrefix${ClassInstanceValidator.CONSTRUCTOR}"
-
-    val constructorProps = descriptorProperties
-      .getVariableIndexedProperties(constructorPrefix, List())
-
-    var i = 0
-    val parameterList: ArrayBuffer[(Class[_], Any)] = new ArrayBuffer
-    while (i < constructorProps.size()) {
-      // nested class instance
-      if (constructorProps(i).containsKey(ClassInstanceValidator.CLASS)) {
-        parameterList += generateInstance(
-          s"$constructorPrefix.$i.",
-          descriptorProperties,
-          classLoader)
-      }
-      // literal value
-      else {
-        val literalValue = LiteralValueValidator
-          .getValue(s"$constructorPrefix.$i.", descriptorProperties)
-        parameterList += ((literalValue.getClass, literalValue))
-      }
-      i += 1
-    }
-    val constructor = try {
-      instanceClass.getConstructor(parameterList.map(_._1): _*)
-    } catch {
-      case e: Exception =>
-        // only log the cause to have clean error messages
-        val msg = s"Cannot find a public constructor with parameter types " +
-          s"'${parameterList.map(_._1.getName).mkString(", ")}' for '$instanceClassName'."
-        LOG.error(msg, e)
-        throw new ValidationException(msg)
-    }
-
-    val instance = try {
-      constructor.newInstance(parameterList.map(_._2.asInstanceOf[AnyRef]): _*)
-    } catch {
-      case e: Exception =>
-        // only log the cause to have clean error messages
-        val msg = s"Error while creating instance of class '$instanceClassName' " +
-          s"with parameter types '${parameterList.map(_._1.getName).mkString(", ")}'."
-        LOG.error(msg, e)
-        throw new ValidationException(msg)
-    }
-
-    (instanceClass, instance)
-  }
-}
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/functions/FunctionServiceTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/functions/FunctionServiceTest.scala
deleted file mode 100644
index 2ffc423..0000000
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/functions/FunctionServiceTest.scala
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions
-
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.descriptors.{ClassInstance, FunctionDescriptor}
-import org.apache.flink.table.functions.FunctionServiceTest.{MultiArgClass, NoArgClass, OneArgClass, PrivateClass}
-import org.junit.Assert.{assertEquals, assertFalse}
-import org.junit.Test
-
-/**
-  * Tests for [[FunctionService]].
-  */
-class FunctionServiceTest {
-
-  @Test(expected = classOf[ValidationException])
-  def testWrongArgsFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(new ClassInstance()
-        .of(classOf[NoArgClass].getName)
-        .parameterString("12"))
-
-    FunctionService.createFunction(descriptor)
-  }
-
-  @Test(expected = classOf[ValidationException])
-  def testPrivateFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(new ClassInstance().of(classOf[PrivateClass].getName))
-
-    FunctionService.createFunction(descriptor)
-  }
-
-  @Test(expected = classOf[ValidationException])
-  def testInvalidClassFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(new ClassInstance().of("this.class.does.not.exist"))
-
-    FunctionService.createFunction(descriptor)
-  }
-
-  @Test(expected = classOf[ValidationException])
-  def testNotFunctionClassFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(new ClassInstance()
-        .of(classOf[java.lang.String].getName)
-        .parameterString("hello"))
-
-    FunctionService.createFunction(descriptor)
-  }
-
-  @Test
-  def testNoArgFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(new ClassInstance().of(classOf[NoArgClass].getName))
-
-    assertEquals(classOf[NoArgClass], FunctionService.createFunction(descriptor).getClass)
-  }
-
-  @Test
-  def testOneArgFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(
-        new ClassInstance()
-          .of(classOf[OneArgClass].getName)
-          .parameterString("false"))
-
-    val actualFunction = FunctionService.createFunction(descriptor)
-
-    assertEquals(classOf[OneArgClass], actualFunction.getClass)
-    assertFalse(actualFunction.asInstanceOf[OneArgClass].field)
-  }
-
-  @Test
-  def testMultiArgFunctionCreation(): Unit = {
-    val descriptor = new FunctionDescriptor()
-      .fromClass(
-        new ClassInstance()
-          .of(classOf[MultiArgClass].getName)
-          .parameter(new java.math.BigDecimal("12.0003"))
-          .parameter(new ClassInstance()
-            .of(classOf[java.math.BigInteger].getName)
-            .parameter("111111111111111111111111111111111")))
-
-    val actualFunction = FunctionService.createFunction(descriptor)
-
-    assertEquals(classOf[MultiArgClass], actualFunction.getClass)
-    assertEquals(
-      new java.math.BigDecimal("12.0003"),
-      actualFunction.asInstanceOf[MultiArgClass].field1)
-    assertEquals(
-      new java.math.BigInteger("111111111111111111111111111111111"),
-      actualFunction.asInstanceOf[MultiArgClass].field2)
-  }
-}
-
-object FunctionServiceTest {
-
-  class NoArgClass
-    extends ScalarFunction
-
-  class OneArgClass(val field: java.lang.Boolean)
-    extends ScalarFunction
-
-  class MultiArgClass(val field1: java.math.BigDecimal, val field2: java.math.BigInteger)
-    extends ScalarFunction
-
-  class PrivateClass private() extends ScalarFunction
-}