From 4276e3035aa883d6b1025b399529902816cafd43 Mon Sep 17 00:00:00 2001 From: ludo Date: Mon, 9 Mar 2020 13:19:11 -0700 Subject: [PATCH 001/308] Update plugin description to mention the function deploy capability. PiperOrigin-RevId: 299917488 --- invoker/function-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index c98d65e7..7c6b5c2b 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -12,7 +12,7 @@ maven-plugin 0.9.1-SNAPSHOT Functions Framework Plugin - A Maven plugin that allows functions to be run locally + A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. http://maven.apache.org From 6f12d068e6ba645d6e12cbe4b828f48cba54c3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Wed, 11 Mar 2020 15:22:20 -0700 Subject: [PATCH 002/308] [maven-release-plugin] prepare release java-function-invoker-parent-1.0.0-alpha-2-rc4 --- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 1c543968..ff21acef 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 com.google.cloud.functions.invoker java-function-invoker - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -101,7 +101,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index 7c6b5c2b..d748cd5f 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 com.google.cloud.functions function-maven-plugin maven-plugin - 0.9.1-SNAPSHOT + 0.9.1 Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 diff --git a/invoker/pom.xml b/invoker/pom.xml index b09fdbd5..b5608bf6 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index d9659932..de5a2dbe 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4-SNAPSHOT + 1.0.0-alpha-2-rc4 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 0862d452dac438b04ae73d2c944ad5c6c51f639b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Wed, 11 Mar 2020 15:22:29 -0700 Subject: [PATCH 003/308] [maven-release-plugin] prepare for next development iteration --- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index ff21acef..26efdd7f 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -101,7 +101,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index d748cd5f..94bb6280 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT com.google.cloud.functions function-maven-plugin maven-plugin - 0.9.1 + 0.9.2-SNAPSHOT Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT diff --git a/invoker/pom.xml b/invoker/pom.xml index b5608bf6..01af5b92 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index de5a2dbe..b7b9d820 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.0-alpha-2-rc4 + 1.0.0-alpha-2-rc5-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 9f350c66e3f18d974dd60b9bc418b6966b810633 Mon Sep 17 00:00:00 2001 From: emcmanus Date: Wed, 11 Mar 2020 17:48:10 -0700 Subject: [PATCH 004/308] Import the modified pom.xml files from the latest release, and update the README to reflect the new version numbers. PiperOrigin-RevId: 300445429 --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 15173130..15a9d87a 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ You can configure the plugin in `pom.xml`: com.google.cloud.functions function-maven-plugin - 0.9 + 0.9.1 com.example.function.Echo @@ -153,7 +153,7 @@ mvn function:run You can alternatively configure the plugin with properties on the command line: ```sh - mvn com.google.cloud.functions:function:0.9:run \ + mvn com.google.cloud.functions:function:0.9.1:run \ -Drun.functionTarget=com.example.function.Echo ``` @@ -164,7 +164,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.0-alpha-2-rc3' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.0-alpha-2-rc4' \ -DoutputDirectory=. ``` @@ -172,7 +172,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.0.0-alpha-2-rc3.jar \ +java -jar java-function-invoker-1.0.0-alpha-2-rc4.jar \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -222,7 +222,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.0.0-alpha-2-rc3.jar \ +java -jar java-function-invoker-1.0.0-alpha-2-rc4.jar \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From a3d23cc12df52cb10ee0102e50cd54eb943527e6 Mon Sep 17 00:00:00 2001 From: emcmanus Date: Thu, 19 Mar 2020 08:54:51 -0700 Subject: [PATCH 005/308] Set the Thread Context ClassLoader while executing function code. Users justifiably expect that the TCCL will be the loader of their code, and lots of things fail to work if that is not true. PiperOrigin-RevId: 301824288 --- .../NewBackgroundFunctionExecutor.java | 20 +++++++++++++------ .../invoker/NewHttpFunctionExecutor.java | 3 +++ .../java/com/example/functionjar/Checker.java | 9 +++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewBackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewBackgroundFunctionExecutor.java index f70c46eb..5dbb89c9 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewBackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewBackgroundFunctionExecutor.java @@ -168,14 +168,18 @@ private static Map httpHeaderMap(HttpServletRequest req) { * unmarshalling this event, if it is a CloudEvent. */ private abstract static class FunctionExecutor { - private final String functionName; + private final Class functionClass; - FunctionExecutor(String functionName) { - this.functionName = functionName; + FunctionExecutor(Class functionClass) { + this.functionClass = functionClass; } final String functionName() { - return functionName; + return functionClass.getCanonicalName(); + } + + final ClassLoader functionClassLoader() { + return functionClass.getClassLoader(); } abstract void serviceLegacyEvent(HttpServletRequest req) @@ -193,7 +197,7 @@ private static class RawFunctionExecutor extends FunctionExecutor> { private final RawBackgroundFunction function; RawFunctionExecutor(RawBackgroundFunction function) { - super(function.getClass().getCanonicalName()); + super(function.getClass()); this.function = function; } @@ -234,7 +238,7 @@ private static class TypedFunctionExecutor extends FunctionExecutor { private final BackgroundFunction function; private TypedFunctionExecutor(Type type, BackgroundFunction function) { - super(function.getClass().getCanonicalName()); + super(function.getClass()); this.type = type; this.function = function; } @@ -287,7 +291,9 @@ Class cloudEventDataType() { @Override public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { String contentType = req.getContentType(); + ClassLoader oldContextLoader = Thread.currentThread().getContextClassLoader(); try { + Thread.currentThread().setContextClassLoader(functionExecutor.functionClassLoader()); if (contentType != null && contentType.startsWith("application/cloudevents+json")) { serviceCloudEvent(req, CloudEventKind.STRUCTURED); } else if (req.getHeader("ce-specversion") != null) { @@ -299,6 +305,8 @@ public void service(HttpServletRequest req, HttpServletResponse res) throws IOEx } catch (Throwable t) { res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); logger.log(Level.WARNING, "Failed to execute " + functionExecutor.functionName(), t); + } finally { + Thread.currentThread().setContextClassLoader(oldContextLoader); } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewHttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewHttpFunctionExecutor.java index 65d102fb..29782301 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewHttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/NewHttpFunctionExecutor.java @@ -61,7 +61,9 @@ public static NewHttpFunctionExecutor forClass(Class functionClass) { public void service(HttpServletRequest req, HttpServletResponse res) { HttpRequestImpl reqImpl = new HttpRequestImpl(req); HttpResponseImpl respImpl = new HttpResponseImpl(res); + ClassLoader oldContextLoader = Thread.currentThread().getContextClassLoader(); try { + Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader()); function.service(reqImpl, respImpl); } catch (Throwable t) { // TODO(b/146510646): this should be logged properly as an exception, but that currently @@ -71,6 +73,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) { t.printStackTrace(); res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { + Thread.currentThread().setContextClassLoader(oldContextLoader); try { // We can't use HttpServletResponse.flushBuffer() because we wrap the PrintWriter // returned by HttpServletResponse in our own BufferedWriter to match our API. diff --git a/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java b/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java index cc750b82..19c78cd2 100644 --- a/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java +++ b/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java @@ -18,6 +18,15 @@ class Checker { void serviceOrAssert(String runtimeClassName) { + // Check that the context class loader is the loader that loaded this class. + if (getClass().getClassLoader() != Thread.currentThread().getContextClassLoader()) { + throw new AssertionError( + String.format( + "ClassLoader mismatch: mine %s; context %s", + getClass().getClassLoader(), + Thread.currentThread().getContextClassLoader())); + } + ClassLoader myLoader = getClass().getClassLoader(); Class