[NO ISSUE] Check if Java UDF classes are assignable to IFunctionFactory

As of now, we instantiate whatever class is specified in an external UDF upon
invocation before checking if it can be cast to an IFunctionFactory.

This might be dangerous if some class in our classloaders contains exploitable
code in static intializers. So we should check if the class is assignable to
IFunctionFactory before attempting to instantiate it.

Change-Id: Id14581cca775b54de6f3fd8c0cf032d7c352bbbe
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/9043
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarJavaFunctionEvaluator.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarJavaFunctionEvaluator.java
index 33b0369..a8d246e 100755
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarJavaFunctionEvaluator.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarJavaFunctionEvaluator.java
@@ -53,9 +53,16 @@
 
         String classname = finfo.getExternalIdentifier().get(0);
         try {
-            Class<?> clazz = Class.forName(classname, true, library.getClassLoader());
-            IFunctionFactory externalFunctionFactory = (IFunctionFactory) clazz.newInstance();
-            externalFunctionInstance = (IExternalScalarFunction) externalFunctionFactory.getExternalFunction();
+            //first, check if this class is assignable to the correct interface before running static initializers that
+            //may be dangerous
+            Class<?> clazz = Class.forName(classname, false, library.getClassLoader());
+            if (IFunctionFactory.class.isAssignableFrom(clazz)) {
+                //check if clazz implements IFunctionFactory
+                IFunctionFactory externalFunctionFactory = (IFunctionFactory) clazz.newInstance();
+                externalFunctionInstance = (IExternalScalarFunction) externalFunctionFactory.getExternalFunction();
+            } else {
+                throw new ClassCastException("Specified class does not implement IFunctionFactory");
+            }
         } catch (Exception e) {
             throw new RuntimeDataException(ErrorCode.LIBRARY_EXTERNAL_FUNCTION_UNABLE_TO_LOAD_CLASS, e, classname);
         }