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 new file mode 100644 index 00000000..91a00aea --- /dev/null +++ b/src/main/java/com/microsoft/azure/functions/worker/broker/EnhancedJavaMethodExecutorImpl.java @@ -0,0 +1,28 @@ +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 a855e7c9..9b72f76d 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,7 +113,8 @@ private void initializeFunctionInstanceInjector() { } private FunctionExecutionMiddleware getFunctionExecutionMiddleWare() { - FunctionExecutionMiddleware functionExecutionMiddleware = new FunctionExecutionMiddleware(JavaMethodExecutor.getInstance()); + FunctionExecutionMiddleware functionExecutionMiddleware = new FunctionExecutionMiddleware( + JavaMethodExecutors.createJavaMethodExecutor(this.classLoaderProvider.createClassLoader())); WorkerLogManager.getSystemLogger().info("Load last middleware: FunctionExecutionMiddleware"); return functionExecutionMiddleware; } @@ -121,21 +122,11 @@ private FunctionExecutionMiddleware getFunctionExecutionMiddleWare() { public Optional invokeMethod(String id, InvocationRequest request, List outputs) throws Exception { ExecutionContextDataSource executionContextDataSource = buildExecutionContext(id, request); - invoke(executionContextDataSource); + this.invocationChainFactory.create().doNext(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 759f575f..7cd16ce1 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,25 +1,14 @@ 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 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); - } +public interface JavaMethodExecutor { + void execute(ExecutionContextDataSource executionContextDataSource) throws Exception; } 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 new file mode 100644 index 00000000..acd37fb9 --- /dev/null +++ b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutorImpl.java @@ -0,0 +1,25 @@ +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 new file mode 100644 index 00000000..309ad7bc --- /dev/null +++ b/src/main/java/com/microsoft/azure/functions/worker/broker/JavaMethodExecutors.java @@ -0,0 +1,16 @@ +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); + } + } +}