From 531587467c045430976053f1c96ef67cb232555c Mon Sep 17 00:00:00 2001 From: kaibocai <89094811+kaibocai@users.noreply.github.com> Date: Wed, 27 Sep 2023 10:37:34 -0500 Subject: [PATCH] Set Thread context classloder for entire middleware chain (#717) * Set Thread context classloder for entire middleware chain * clean up code * clean up --- .../EnhancedJavaMethodExecutorImpl.java | 28 ------------------- .../worker/broker/JavaFunctionBroker.java | 15 ++++++++-- .../worker/broker/JavaMethodExecutor.java | 21 ++++++++++---- .../worker/broker/JavaMethodExecutorImpl.java | 25 ----------------- .../worker/broker/JavaMethodExecutors.java | 16 ----------- 5 files changed, 28 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java delete mode 100644 src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java delete mode 100644 src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutors.java diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java b/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java deleted file mode 100644 index 91a00ae..0000000 --- a/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.microsoft.azure.functions.worker.broker; - -import com.microsoft.azure.functions.worker.binding.*; - -/** - * Used to executor of arbitrary Java method in any JAR using reflection. - * Thread-Safety: Multiple thread. - */ -public class EnhancedJavaMethodExecutorImpl implements JavaMethodExecutor { - - private final ClassLoader classLoader; - - public EnhancedJavaMethodExecutorImpl(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - public void execute(ExecutionContextDataSource executionContextDataSource) throws Exception { - try { - Thread.currentThread().setContextClassLoader(this.classLoader); - Object retValue = ParameterResolver.resolveArguments(executionContextDataSource) - .orElseThrow(() -> new NoSuchMethodException("Cannot locate the method signature with the given input")) - .invoke(executionContextDataSource::getFunctionInstance); - executionContextDataSource.updateReturnValue(retValue); - } finally { - Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); - } - } -} 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 9b72f76..a855e7c 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 @@ -113,8 +113,7 @@ public class JavaFunctionBroker { } private FunctionExecutionMiddleware getFunctionExecutionMiddleWare() { - FunctionExecutionMiddleware functionExecutionMiddleware = new FunctionExecutionMiddleware( - JavaMethodExecutors.createJavaMethodExecutor(this.classLoaderProvider.createClassLoader())); + FunctionExecutionMiddleware functionExecutionMiddleware = new FunctionExecutionMiddleware(JavaMethodExecutor.getInstance()); WorkerLogManager.getSystemLogger().info("Load last middleware: FunctionExecutionMiddleware"); return functionExecutionMiddleware; } @@ -122,11 +121,21 @@ public class JavaFunctionBroker { public Optional invokeMethod(String id, InvocationRequest request, List outputs) throws Exception { ExecutionContextDataSource executionContextDataSource = buildExecutionContext(id, request); - this.invocationChainFactory.create().doNext(executionContextDataSource); + invoke(executionContextDataSource); outputs.addAll(executionContextDataSource.getDataStore().getOutputParameterBindings(true)); return executionContextDataSource.getDataStore().getDataTargetTypedValue(BindingDataStore.RETURN_NAME); } + private void invoke(ExecutionContextDataSource executionContextDataSource) throws Exception { + ClassLoader prevContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(classLoaderProvider.createClassLoader()); + this.invocationChainFactory.create().doNext(executionContextDataSource); + } finally { + Thread.currentThread().setContextClassLoader(prevContextClassLoader); + } + } + private ExecutionContextDataSource buildExecutionContext(String id, InvocationRequest request) throws NoSuchMethodException { ImmutablePair methodEntry = this.methods.get(id); diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutor.java b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutor.java index 7cd16ce..759f575 100644 --- a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutor.java +++ b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutor.java @@ -1,14 +1,25 @@ package com.microsoft.azure.functions.worker.broker; - -import java.util.*; import com.microsoft.azure.functions.worker.binding.*; - /** * Used to executor of arbitrary Java method in any JAR using reflection. * Thread-Safety: Multiple thread. */ -public interface JavaMethodExecutor { - void execute(ExecutionContextDataSource executionContextDataSource) throws Exception; +public class JavaMethodExecutor { + + private static final JavaMethodExecutor INSTANCE = new JavaMethodExecutor(); + + public static JavaMethodExecutor getInstance(){ + return INSTANCE; + } + + private JavaMethodExecutor() {} + + public void execute(ExecutionContextDataSource executionContextDataSource) throws Exception { + Object retValue = ParameterResolver.resolveArguments(executionContextDataSource) + .orElseThrow(() -> new NoSuchMethodException("Cannot locate the method signature with the given input")) + .invoke(executionContextDataSource::getFunctionInstance); + executionContextDataSource.updateReturnValue(retValue); + } } 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 acd37fb..0000000 --- a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.microsoft.azure.functions.worker.broker; - -import com.microsoft.azure.functions.worker.binding.*; - -/** - * Used to executor of arbitrary Java method in any JAR using reflection. - * Thread-Safety: Multiple thread. - */ -public class JavaMethodExecutorImpl implements JavaMethodExecutor { - - private static final JavaMethodExecutorImpl INSTANCE = new JavaMethodExecutorImpl(); - - public static JavaMethodExecutorImpl getInstance(){ - return INSTANCE; - } - - private JavaMethodExecutorImpl () {} - - public void execute(ExecutionContextDataSource executionContextDataSource) throws Exception { - Object retValue = ParameterResolver.resolveArguments(executionContextDataSource) - .orElseThrow(() -> new NoSuchMethodException("Cannot locate the method signature with the given input")) - .invoke(executionContextDataSource::getFunctionInstance); - executionContextDataSource.updateReturnValue(retValue); - } -} diff --git a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutors.java b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutors.java deleted file mode 100644 index 309ad7b..0000000 --- a/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutors.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.microsoft.azure.functions.worker.broker; - -import com.microsoft.azure.functions.worker.WorkerLogManager; -import org.apache.commons.lang3.SystemUtils; - -public class JavaMethodExecutors { - public static JavaMethodExecutor createJavaMethodExecutor(ClassLoader classLoader) { - if(SystemUtils.IS_JAVA_1_8) { - WorkerLogManager.getSystemLogger().info("Loading JavaMethodExecutorImpl"); - return JavaMethodExecutorImpl.getInstance(); - } else { - WorkerLogManager.getSystemLogger().info("Loading EnhancedJavaMethodExecutorImpl"); - return new EnhancedJavaMethodExecutorImpl(classLoader); - } - } -}