Repository: Azure/azure-functions-java-worker
Pull request #611 (2022-08-11 23:13:49)

migrate java8 to same logic as java11
<!-- Please provide all the information below.  -->

### Issue describing the changes in this PR

close https://github.com/Azure/azure-functions-java-worker/issues/533

### Pull request checklist

* [X] My changes **do not** require documentation changes
  * [ ] Otherwise: Documentation issue linked to PR
* [X] My changes **should not** be added to the release notes for the next release
  * [ ] Otherwise: I've added my notes to `release_notes.md`
* [X] My changes **do not** need to be backported to a previous version
  * [ ] Otherwise: Backport tracked by issue/PR #issue_or_pr
* [X] I have added all required tests (Unit tests, E2E tests)

<!-- Optional: delete if not applicable  -->
### Additional information

Additional PR information


Patch:
diff --git a/src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java b/src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java
index 49aed25..ed3f1b5 100644
--- a/src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java
+++ b/src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java
@@ -28,7 +28,7 @@ public class JavaWorkerClient implements AutoCloseable {
         this.channel = chanBuilder.build();
         this.peer = new AtomicReference<>(null);
         this.handlerSuppliers = new HashMap<>();
-        this.classPathProvider = new FactoryClassLoader().createClassLoaderProvider();
+        this.classPathProvider =  new FunctionClassLoaderProvider();
         
         this.addHandlers();
     }
diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/FactoryJavaMethodExecutor.java b/src/main/java/com/microsoft/azure/functions/worker/broker/FactoryJavaMethodExecutor.java
deleted file mode 100644
index f2c4bab..0000000
--- a/src/main/java/com/microsoft/azure/functions/worker/broker/FactoryJavaMethodExecutor.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.microsoft.azure.functions.worker.broker;
-
-import com.microsoft.azure.functions.rpc.messages.BindingInfo;
-import com.microsoft.azure.functions.worker.WorkerLogManager;
-import com.microsoft.azure.functions.worker.description.FunctionMethodDescriptor;
-import com.microsoft.azure.functions.worker.reflect.ClassLoaderProvider;
-import org.apache.commons.lang3.SystemUtils;
-
-import java.net.MalformedURLException;
-import java.util.Map;
-
-public class FactoryJavaMethodExecutor {
-    public JavaMethodExecutor getJavaMethodExecutor(FunctionMethodDescriptor descriptor, Map<String, BindingInfo> bindings, ClassLoaderProvider classLoaderProvider)
-            throws MalformedURLException, ClassNotFoundException, NoSuchMethodException {
-        if(SystemUtils.IS_JAVA_1_8) {
-            WorkerLogManager.getSystemLogger().info("Loading JavaMethodExecutorImpl");
-            return new JavaMethodExecutorImpl(descriptor, bindings, classLoaderProvider);
-        } else {
-            WorkerLogManager.getSystemLogger().info("Loading EnhancedJavaMethodExecutorImpl");
-            return new EnhancedJavaMethodExecutorImpl(descriptor, bindings, classLoaderProvider);
-        }
-    }
-}
diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java b/src/main/java/com/microsoft/azure/functions/worker/broker/FunctionMethodExecutorImpl.java
similarity index 92%
rename from src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java
rename to src/main/java/com/microsoft/azure/functions/worker/broker/FunctionMethodExecutorImpl.java
index 2a6a031..c4a4da1 100644
--- a/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java
+++ b/src/main/java/com/microsoft/azure/functions/worker/broker/FunctionMethodExecutorImpl.java
@@ -12,8 +12,8 @@ import com.microsoft.azure.functions.rpc.messages.*;
  * Used to executor of arbitrary Java method in any JAR using reflection.
  * Thread-Safety: Multiple thread.
  */
-public class EnhancedJavaMethodExecutorImpl implements JavaMethodExecutor {
-    public EnhancedJavaMethodExecutorImpl(FunctionMethodDescriptor descriptor, Map<String, BindingInfo> bindingInfos, ClassLoaderProvider classLoaderProvider)
+public class FunctionMethodExecutorImpl implements JavaMethodExecutor {
+    public FunctionMethodExecutorImpl(FunctionMethodDescriptor descriptor, Map<String, BindingInfo> bindingInfos, ClassLoaderProvider classLoaderProvider)
             throws ClassNotFoundException, NoSuchMethodException
     {
         descriptor.validateMethodInfo();
diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBroker.java b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBroker.java
index 7a10ac1..b95a786 100644
--- a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBroker.java
+++ b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBroker.java
@@ -10,7 +10,6 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import com.microsoft.azure.functions.rpc.messages.*;
 import com.microsoft.azure.functions.worker.Constants;
-import com.microsoft.azure.functions.worker.WorkerLogManager;
 import com.microsoft.azure.functions.worker.binding.BindingDataStore;
 import com.microsoft.azure.functions.worker.binding.ExecutionRetryContext;
 import com.microsoft.azure.functions.worker.binding.ExecutionTraceContext;
@@ -35,7 +34,7 @@ public class JavaFunctionBroker {
 		descriptor.validate();
 
 		addSearchPathsToClassLoader(descriptor);
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, classLoaderProvider);
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, classLoaderProvider);
 
 		this.methods.put(descriptor.getId(), new ImmutablePair<>(descriptor.getName(), executor));
 	}
diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java
deleted file mode 100644
index bad1d2e..0000000
--- a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.microsoft.azure.functions.worker.broker;
-
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-
-import com.microsoft.azure.functions.worker.binding.*;
-import com.microsoft.azure.functions.worker.description.*;
-import com.microsoft.azure.functions.worker.reflect.*;
-import com.microsoft.azure.functions.rpc.messages.*;
-
-/**
- * Used to executor of arbitrary Java method in any JAR using reflection.
- * Thread-Safety: Multiple thread.
- */
-public class JavaMethodExecutorImpl implements JavaMethodExecutor {
-    public JavaMethodExecutorImpl(FunctionMethodDescriptor descriptor, Map<String, BindingInfo> bindingInfos, ClassLoaderProvider classLoaderProvider)
-            throws MalformedURLException, ClassNotFoundException, NoSuchMethodException
-    {
-        descriptor.validateMethodInfo();
-
-        this.containingClass = getContainingClass(descriptor.getFullClassName(), classLoaderProvider);
-        this.overloadResolver = new ParameterResolver();
-
-        for (Method method : this.containingClass.getMethods()) {
-            if (method.getDeclaringClass().getName().equals(descriptor.getFullClassName()) && method.getName().equals(descriptor.getMethodName())) {
-                this.overloadResolver.addCandidate(method);
-            }
-        }
-
-        if (!this.overloadResolver.hasCandidates()) {
-            throw new NoSuchMethodException("There are no methods named \"" + descriptor.getName() + "\" in class \"" + descriptor.getFullClassName() + "\"");
-        }
-
-        if (this.overloadResolver.hasMultipleCandidates()) {
-            throw new UnsupportedOperationException("Found more than one function with method name \"" + descriptor.getName() + "\" in class \"" + descriptor.getFullClassName() + "\"");
-        }
-
-        this.bindingDefinitions = new HashMap<>();
-
-        for (Map.Entry<String, BindingInfo> entry : bindingInfos.entrySet()) {
-            this.bindingDefinitions.put(entry.getKey(), new BindingDefinition(entry.getKey(), entry.getValue()));
-        }
-    }
-
-    public Map<String, BindingDefinition> getBindingDefinitions() { return this.bindingDefinitions; }
-
-    public ParameterResolver getOverloadResolver() { return this.overloadResolver; }
-
-    public void execute(BindingDataStore dataStore) throws Exception {
-        Object retValue = this.overloadResolver.resolve(dataStore)
-                .orElseThrow(() -> new NoSuchMethodException("Cannot locate the method signature with the given input"))
-                .invoke(() -> this.containingClass.newInstance());
-        dataStore.setDataTargetValue(BindingDataStore.RETURN_NAME, retValue);
-    }
-
-    private Class<?> getContainingClass(String className, ClassLoaderProvider classLoaderProvider) throws ClassNotFoundException {
-        ClassLoader classLoader = classLoaderProvider.createClassLoader();
-        return Class.forName(className, true, classLoader);
-    }
-
-    private Class<?> containingClass;
-    private final ParameterResolver overloadResolver;
-    private final Map<String, BindingDefinition> bindingDefinitions;
-}
diff --git a/src/main/java/com/microsoft/azure/functions/worker/reflect/DefaultClassLoaderProvider.java b/src/main/java/com/microsoft/azure/functions/worker/reflect/DefaultClassLoaderProvider.java
deleted file mode 100644
index fecc55b..0000000
--- a/src/main/java/com/microsoft/azure/functions/worker/reflect/DefaultClassLoaderProvider.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.microsoft.azure.functions.worker.reflect;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.microsoft.azure.functions.worker.*;
-
-/**
- * @author Kevin Hillinger Default implementation of the class loader provider
- */
-public class DefaultClassLoaderProvider implements ClassLoaderProvider {
-  public DefaultClassLoaderProvider() {
-    customerUrls = Collections.newSetFromMap(new ConcurrentHashMap<URL, Boolean>());
-    workerUrls = Collections.newSetFromMap(new ConcurrentHashMap<URL, Boolean>());
-  }
-
-  /*
-   * @see com.microsoft.azure.functions.reflect.ClassLoaderProvider#createClassLoader()
-   */
-  @Override
-  public ClassLoader createClassLoader() {
-    List<URL> urlsList = new ArrayList<>();
-    urlsList.addAll(customerUrls);
-    urlsList.addAll(workerUrls);
-    URL[] urlsForClassLoader = urlsList.toArray(new URL[0]);
-    URLClassLoader classLoader = new URLClassLoader(urlsForClassLoader);
-    Thread.currentThread().setContextClassLoader(classLoader);
-    return classLoader;
-  }
-
-  @Override
-  public void addCustomerUrl(URL url) throws IOException {
-    if (customerUrls.contains(url)) {
-      return;
-    }
-    WorkerLogManager.getSystemLogger().info("Loading customer file URL: " + url);
-    customerUrls.add(url);
-    addUrlToSystemClassLoader(url);
-  }
-
-  @Override
-  public void addWorkerUrl(URL url) throws IOException {
-    if (workerUrls.contains(url)) {
-      return;
-    }
-    WorkerLogManager.getSystemLogger().info("Loading worker file URL: " + url);
-    workerUrls.add(url);
-    addUrlToSystemClassLoader(url);
-  }
-
-  public static boolean isUrlPointingToAFile(URL url) throws UnsupportedEncodingException {
-    String decodedPath = URLDecoder.decode(url.getPath(), "UTF-8");
-    File file = new File(decodedPath);
-    return file.exists();
-  }
-
-  private void addUrlToSystemClassLoader(URL url) throws IOException {
-    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
-    Class<?> sysclass = URLClassLoader.class;
-
-    try {
-      Method method = sysclass.getDeclaredMethod(SYS_LOADER_ADDURL_METHOD_NAME, parameters);
-      method.setAccessible(true);
-      method.invoke(sysloader, new Object[] { url });
-    } catch (Throwable t) {
-      throw new IOException("Error adding " + url + " to system classloader");
-    }
-
-  }
-
-  private static final String SYS_LOADER_ADDURL_METHOD_NAME = "addURL";
-  private static final Class<?>[] parameters = new Class[] { URL.class };
-  private final Set<URL> customerUrls;
-  private final Set<URL> workerUrls;
-}
diff --git a/src/main/java/com/microsoft/azure/functions/worker/reflect/FactoryClassLoader.java b/src/main/java/com/microsoft/azure/functions/worker/reflect/FactoryClassLoader.java
deleted file mode 100644
index dcb5c86..0000000
--- a/src/main/java/com/microsoft/azure/functions/worker/reflect/FactoryClassLoader.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.microsoft.azure.functions.worker.reflect;
-
-import org.apache.commons.lang3.SystemUtils;
-
-public class FactoryClassLoader {
-    public ClassLoaderProvider createClassLoaderProvider(){
-        if(SystemUtils.IS_JAVA_1_8) {
-            return new DefaultClassLoaderProvider();
-        } else {
-            return new EnhancedClassLoaderProvider();
-        }
-    }
-}
diff --git a/src/main/java/com/microsoft/azure/functions/worker/reflect/EnhancedClassLoaderProvider.java b/src/main/java/com/microsoft/azure/functions/worker/reflect/FunctionClassLoaderProvider.java
similarity index 70%
rename from src/main/java/com/microsoft/azure/functions/worker/reflect/EnhancedClassLoaderProvider.java
rename to src/main/java/com/microsoft/azure/functions/worker/reflect/FunctionClassLoaderProvider.java
index 7ebd723..066a965 100644
--- a/src/main/java/com/microsoft/azure/functions/worker/reflect/EnhancedClassLoaderProvider.java
+++ b/src/main/java/com/microsoft/azure/functions/worker/reflect/FunctionClassLoaderProvider.java
@@ -9,8 +9,8 @@ import java.util.concurrent.*;
 
 import com.microsoft.azure.functions.worker.*;
 
-public class EnhancedClassLoaderProvider implements ClassLoaderProvider {
-    public EnhancedClassLoaderProvider() {
+public class FunctionClassLoaderProvider implements ClassLoaderProvider {
+    public FunctionClassLoaderProvider() {
         customerUrls = Collections.newSetFromMap(new ConcurrentHashMap<URL, Boolean>());
         workerUrls = Collections.newSetFromMap(new ConcurrentHashMap<URL, Boolean>());
     }
@@ -28,7 +28,6 @@ public class EnhancedClassLoaderProvider implements ClassLoaderProvider {
                     urlsList.addAll(workerUrls);
                     URL[] urlsForClassLoader = urlsList.toArray(new URL[0]);
                     URLClassLoader loader = new URLClassLoader(urlsForClassLoader);
-                    loadDrivers(loader);
                     classLoaderInstance = loader;
                 }
             }
@@ -36,23 +35,6 @@ public class EnhancedClassLoaderProvider implements ClassLoaderProvider {
         return classLoaderInstance;
     }
 
-    private void loadDrivers(URLClassLoader classLoader) {
-        Thread.currentThread().setContextClassLoader(classLoader);
-        try {
-            ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
-            Iterator<Driver> driversIterator = loadedDrivers.iterator();
-            try {
-                while (driversIterator.hasNext()) {
-                    driversIterator.next();
-                }
-            } catch (Throwable t) {
-                // Do nothing
-            }
-        } finally {
-            Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
-        }
-    }
-
     @Override
     public void addCustomerUrl(URL url) throws IOException {
         if (customerUrls.contains(url)) {


Test patch:
diff --git a/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java b/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java
index 231c1d6..13f0f25 100644
--- a/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java
+++ b/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java
@@ -3,7 +3,7 @@ package com.microsoft.azure.functions.worker.broker;
 import com.microsoft.azure.functions.rpc.messages.InvocationRequest;
 import com.microsoft.azure.functions.rpc.messages.ParameterBinding;
 import com.microsoft.azure.functions.rpc.messages.TypedData;
-import com.microsoft.azure.functions.worker.reflect.DefaultClassLoaderProvider;
+import com.microsoft.azure.functions.worker.reflect.FunctionClassLoaderProvider;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -57,7 +57,7 @@ public class JavaFunctionBrokerTest {
         triggerMetadata.put("sys", sys);
         when(request.getTriggerMetadataMap()).thenReturn(Collections.unmodifiableMap(triggerMetadata));
 
-        JavaFunctionBroker broker = new JavaFunctionBroker(new DefaultClassLoaderProvider());
+        JavaFunctionBroker broker = new JavaFunctionBroker(new FunctionClassLoaderProvider());
         Map<String, TypedData> actualTriggerMetadata = broker.getTriggerMetadataMap(request);
         TypedData actual = actualTriggerMetadata.get("$request");
         assertEquals(actual.getString(), expectedData);
@@ -97,7 +97,7 @@ public class JavaFunctionBrokerTest {
         when(request.getTriggerMetadataMap()).thenReturn(Collections.unmodifiableMap(triggerMetadata));
 
         int expectedCount = request.getTriggerMetadataMap().size();
-        JavaFunctionBroker broker = new JavaFunctionBroker(new DefaultClassLoaderProvider());
+        JavaFunctionBroker broker = new JavaFunctionBroker(new FunctionClassLoaderProvider());
         Map<String, TypedData> actualTriggerMetadata = broker.getTriggerMetadataMap(request);
         // In case of non-http request, it will not modify the triggerMetadata
         assertEquals(expectedCount, actualTriggerMetadata.size());
diff --git a/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaMethodExecutorTests.java b/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaMethodExecutorTests.java
index c1bad3a..48a8ebb 100644
--- a/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaMethodExecutorTests.java
+++ b/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaMethodExecutorTests.java
@@ -18,7 +18,7 @@ public class JavaMethodExecutorTests {
 		FunctionMethodDescriptor descriptor = new FunctionMethodDescriptor("testid", "TestHttpTrigger","com.microsoft.azure.functions.worker.broker.tests.TestFunctionsClass.TestHttpTrigger","TestFunctionsClass.jar");
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
 		assertTrue(executor.getOverloadResolver().hasCandidates());
 		assertFalse(executor.getOverloadResolver().hasMultipleCandidates());
     }
@@ -28,7 +28,7 @@ public class JavaMethodExecutorTests {
 		FunctionMethodDescriptor descriptor = new FunctionMethodDescriptor("testid", "TestHttpTrigger1","com.microsoft.azure.functions.worker.broker.tests.TestFunctionsClass.TestHttpTrigger1","TestFunctionsClass.jar");
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
 		
     }
 	
@@ -37,7 +37,7 @@ public class JavaMethodExecutorTests {
 		FunctionMethodDescriptor descriptor = new FunctionMethodDescriptor("testid", "TestHttpTriggerOverload","com.microsoft.azure.functions.worker.broker.tests.TestFunctionsClass.TestHttpTriggerOverload","TestFunctionsClass.jar");
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
     }
 
 	@Test
@@ -46,7 +46,7 @@ public class JavaMethodExecutorTests {
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
 		System.setProperty("java.specification.version", "11");
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
 		assertTrue(executor.getOverloadResolver().hasCandidates());
 		assertFalse(executor.getOverloadResolver().hasMultipleCandidates());
 	}
@@ -57,7 +57,7 @@ public class JavaMethodExecutorTests {
 		FunctionMethodDescriptor descriptor = new FunctionMethodDescriptor("testid", "TestHttpTrigger1","com.microsoft.azure.functions.worker.broker.tests.TestFunctionsClass.TestHttpTrigger1","TestFunctionsClass.jar");
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
 
 	}
 
@@ -67,6 +67,6 @@ public class JavaMethodExecutorTests {
 		FunctionMethodDescriptor descriptor = new FunctionMethodDescriptor("testid", "TestHttpTriggerOverload","com.microsoft.azure.functions.worker.broker.tests.TestFunctionsClass.TestHttpTriggerOverload","TestFunctionsClass.jar");
 		Map<String, BindingInfo> bindings = new HashMap<>();
 		bindings.put("$return", BindingInfo.newBuilder().setDirection(BindingInfo.Direction.out).build());
-		JavaMethodExecutor executor = new FactoryJavaMethodExecutor().getJavaMethodExecutor(descriptor, bindings, new FactoryClassLoader().createClassLoaderProvider());
+		JavaMethodExecutor executor = new FunctionMethodExecutorImpl(descriptor, bindings, new FunctionClassLoaderProvider());
 	}
 }
diff --git a/src/test/java/com/microsoft/azure/functions/worker/handler/tests/FunctionEnvironmentReloadRequestHandlerTests.java b/src/test/java/com/microsoft/azure/functions/worker/handler/tests/FunctionEnvironmentReloadRequestHandlerTests.java
index 4793d52..e07e0d1 100644
--- a/src/test/java/com/microsoft/azure/functions/worker/handler/tests/FunctionEnvironmentReloadRequestHandlerTests.java
+++ b/src/test/java/com/microsoft/azure/functions/worker/handler/tests/FunctionEnvironmentReloadRequestHandlerTests.java
@@ -7,17 +7,17 @@ import static org.junit.Assert.assertNull;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.microsoft.azure.functions.worker.reflect.FunctionClassLoaderProvider;
 import org.junit.Test;
 
 import com.microsoft.azure.functions.worker.broker.JavaFunctionBroker;
 import com.microsoft.azure.functions.worker.handler.FunctionEnvironmentReloadRequestHandler;
-import com.microsoft.azure.functions.worker.reflect.DefaultClassLoaderProvider;
 
 public class FunctionEnvironmentReloadRequestHandlerTests {
 
 	@Test
 	public void SetEnv_Succeeds() throws Exception {
-		DefaultClassLoaderProvider classLoader = new DefaultClassLoaderProvider();
+		FunctionClassLoaderProvider classLoader = new FunctionClassLoaderProvider();
 		JavaFunctionBroker broker = new JavaFunctionBroker(classLoader);
 		FunctionEnvironmentReloadRequestHandler envHandler = new FunctionEnvironmentReloadRequestHandler(broker);
 
@@ -35,7 +35,7 @@ public class FunctionEnvironmentReloadRequestHandlerTests {
 
 	@Test
 	public void SetEnv_Null_Succeeds() throws Exception {
-		DefaultClassLoaderProvider classLoader = new DefaultClassLoaderProvider();
+		FunctionClassLoaderProvider classLoader = new FunctionClassLoaderProvider();
 		JavaFunctionBroker broker = new JavaFunctionBroker(classLoader);
 		FunctionEnvironmentReloadRequestHandler envHandler = new FunctionEnvironmentReloadRequestHandler(broker);
 
diff --git a/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/DefaultClassLoaderProviderTests.java b/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/DefaultClassLoaderProviderTests.java
deleted file mode 100644
index 7bcd562..0000000
--- a/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/DefaultClassLoaderProviderTests.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.microsoft.azure.functions.worker.reflect.tests;
-
-import java.io.*;
-import java.net.*;
-
-import static org.junit.Assert.*;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.*;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-import com.microsoft.azure.functions.worker.reflect.DefaultClassLoaderProvider;
-
-@RunWith(Parameterized.class)
-public class DefaultClassLoaderProviderTests {
-
-	@Parameters
-	public static Object[] data() {
-		return new Object[] { "nospace.txt", "with space.txt" };
-	}
-
-	@Parameter
-	public String filePath;
-
-	@Rule
-	public TemporaryFolder testFolder = new TemporaryFolder();
-
-	@Test
-	public void isUrlPointingToAFile_Returns_True() throws IOException {
-		File createdFile = testFolder.newFile(filePath);
-		boolean fileExists = DefaultClassLoaderProvider.isUrlPointingToAFile(createdFile.toURI().toURL());
-		assertTrue(fileExists);
-	}
-
-	@Test
-	public void isUrlPointingToAFile_False() throws IOException {
-		String dummyFile = "filedoesnotexist.txt";
-		URL jarUrl = new File(dummyFile).toURI().toURL();
-		boolean fileExists = DefaultClassLoaderProvider.isUrlPointingToAFile(jarUrl);
-		assertFalse(fileExists);
-	}
-}
diff --git a/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/FunctionClassLoaderProviderTests.java b/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/FunctionClassLoaderProviderTests.java
new file mode 100644
index 0000000..5bad0d2
--- /dev/null
+++ b/src/test/java/com/microsoft/azure/functions/worker/reflect/tests/FunctionClassLoaderProviderTests.java
@@ -0,0 +1,35 @@
+package com.microsoft.azure.functions.worker.reflect.tests;
+
+import static org.junit.Assert.*;
+
+import com.microsoft.azure.functions.worker.reflect.FunctionClassLoaderProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+
+@RunWith(Parameterized.class)
+public class FunctionClassLoaderProviderTests {
+
+	@Parameters
+	public static Object[] data() {
+		return new Object[] { "nospace.txt", "with space.txt" };
+	}
+
+	@Parameter
+	public String filePath;
+
+	@Rule
+	public TemporaryFolder testFolder = new TemporaryFolder();
+
+	@Test
+	public void testSingleton() {
+		ClassLoader classLoader1 = new FunctionClassLoaderProvider().createClassLoader();
+		ClassLoader classLoader2 = new FunctionClassLoaderProvider().createClassLoader();
+		assertEquals(classLoader1, classLoader2);
+	}
+}