diff --git a/README.md b/README.md index 4c32a026..816327d3 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ |Branch|Status| |---|---| -|master|[![Build status](https://ci.appveyor.com/api/projects/status/ebphtfegnposba6w?svg=true)](https://ci.appveyor.com/project/appsvc/azure-functions-java-worker?branch=master)| -|dev|[![Build status](https://ci.appveyor.com/api/projects/status/ebphtfegnposba6w?svg=true)](https://ci.appveyor.com/project/appsvc/azure-functions-java-worker?branch=dev)| +|master|[![Build status](https://dev.azure.com/azfunc/Azure%20Functions/_apis/build/status/Azure.azure-functions-java-worker?branchName=master)](https://dev.azure.com/azfunc/Azure%20Functions/_build/latest?definitionId=20&branchName=master)| +|dev|[![Build status](https://dev.azure.com/azfunc/Azure%20Functions/_apis/build/status/Azure.azure-functions-java-worker?branchName=dev)](https://dev.azure.com/azfunc/Azure%20Functions/_build/latest?definitionId=20&branchName=dev)| # Contributing @@ -104,6 +104,10 @@ Simply using the following command to do so (if there are dependency errors, run mvn javadoc:javadoc ``` +# Development Notes + +Java worker now shades all its jars, to introduce any new jars it is required by the developers to add a section in the pom file to relocate it. + # Coding Convention ## Version Management diff --git a/appveyor.yml b/appveyor.yml index c176ce7e..ee13f755 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,7 +30,7 @@ build_script: Write-Host “Found git tag." } else { - $buildNumber = "1.6.2-$env:APPVEYOR_BUILD_NUMBER" + $buildNumber = "1.7.1-$env:APPVEYOR_BUILD_NUMBER" Write-Host “git tag not found. Setting package suffix to '$buildNumber'" } .\package.ps1 -buildNumber $buildNumber diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6c51984e..db40d8fd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,10 +19,10 @@ steps: Write-Host “Found git tag." } else { - $buildNumber = "1.6.2-$(Build.BuildId)" + $buildNumber = "1.7.1-$(Build.BuildId)" Write-Host “git tag not found. Setting package suffix to '$buildNumber'" } - .\package.ps1 -buildNumber $buildNumber + .\package-pipeline.ps1 -buildNumber $buildNumber displayName: 'Executing build script' - task: CopyFiles@2 inputs: @@ -49,6 +49,22 @@ steps: SBQueueName: $(SBQueueName) displayName: 'Build & Run tests for java 8' continueOnError: false +- pwsh: | + .\build-run-tests-pipeline.ps1 + env: + FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS: 'True' + AzureWebJobsStorage: $(AzureWebJobsStorage) + AzureWebJobsCosmosDBConnectionString: $(AzureWebJobsCosmosDBConnectionString) + AzureWebJobsServiceBus: $(AzureWebJobsServiceBus) + AzureWebJobsEventHubReceiver: $(AzureWebJobsEventHubReceiver) + AzureWebJobsEventHubSender: $(AzureWebJobsEventHubSender) + AzureWebJobsEventHubPath: $(AzureWebJobsEventHubPath) + SBTopicName: $(SBTopicName) + SBTopicSubName: $(SBTopicSubName) + CosmosDBDatabaseName: $(CosmosDBDatabaseName) + SBQueueName: $(SBQueueName) + displayName: 'Build & Run tests for java 8 Customer jar loaded first' + continueOnError: false - pwsh: | .\build-run-tests-pipeline.ps1 env: diff --git a/e2e-nightly-cli-azure-pipelines.yml b/e2e-nightly-cli-azure-pipelines.yml index 098f7677..89085f36 100644 --- a/e2e-nightly-cli-azure-pipelines.yml +++ b/e2e-nightly-cli-azure-pipelines.yml @@ -19,7 +19,7 @@ steps: Write-Host “Found git tag." } else { - $buildNumber = "1.6.2-$(Build.BuildId)" + $buildNumber = "1.7.1-$(Build.BuildId)" Write-Host “git tag not found. Setting package suffix to '$buildNumber'" } .\package.ps1 -buildNumber $buildNumber diff --git a/endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/HttpEndToEndTests.cs b/endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/HttpEndToEndTests.cs index 88346e45..14537e1c 100644 --- a/endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/HttpEndToEndTests.cs +++ b/endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/HttpEndToEndTests.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; using System.Net; using System.Threading.Tasks; using Xunit; @@ -33,5 +34,26 @@ public async Task HttpTrigger_ReturnsCustomCode() { Assert.True(await Utilities.InvokeHttpTrigger("HttpTriggerCustomCode", "?&name=Test", HttpStatusCode.OK, "Test", 209)); } + + [Fact] + public async Task HttpTriggerJavaClassLoader() + { + // The e2e project has newer jars than the one we use in the worker. + // The purpose of this test will be called for three scenarios: + // 1. Java 11 -- Client code takes presence. -- works fine. + // 2. Java 8 with no Application settings, worker lib jars takes presence -- throw exception + // 3. Java 8 with with Application settings, worker lib jars takes presence -- works fine. + + String value = Environment.GetEnvironmentVariable("FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS"); + String java_home = Environment.GetEnvironmentVariable("JAVA_HOME"); + if (java_home.Contains("zulu-11") || (value != null && value.ToLower().Equals("true"))) + { + Assert.True(await Utilities.InvokeHttpTrigger("HttpTriggerJavaClassLoader", "?&name=Test", HttpStatusCode.OK, "Test")); + } + else + { + Assert.True(await Utilities.InvokeHttpTrigger("HttpTriggerJavaClassLoader", "?&name=Test", HttpStatusCode.InternalServerError, "")); + } + } } } diff --git a/endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/HttpTriggerTests.java b/endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/HttpTriggerTests.java index cf57768a..739df76f 100644 --- a/endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/HttpTriggerTests.java +++ b/endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/HttpTriggerTests.java @@ -46,12 +46,6 @@ public HttpResponseMessage HttpTriggerJava( } } - Gson a = new Gson(); - -// if(!SystemUtils.IS_JAVA_15) { -// context.getLogger().info("Java version not 15"); -// } - get("https://httpstat.us/200"); if (name == null ) { @@ -108,4 +102,28 @@ public HttpResponseMessage HttpTriggerCustomCode( return request.createResponseBuilder(HttpStatusType.custom(209)).body("Hello, " + name).build(); } } + + @FunctionName("HttpTriggerJavaClassLoader") + public HttpResponseMessage HttpTriggerJavaClassLoader( + @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, + final ExecutionContext context + ) throws Exception { + context.getLogger().info("Java HTTP trigger processed a request."); + + // Parse query parameters + String query = request.getQueryParameters().get("name"); + String name = request.getBody().orElse(query); + + //Make sure there is no class not found excption. + new Gson(); + + if(!SystemUtils.IS_JAVA_15) { + context.getLogger().info("Java version not 15"); + } + + if (name == null ) { + return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build(); + } + return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build(); + } } diff --git a/lib_worker_1.6.2/animal-sniffer-annotations-1.17.jar b/lib_worker_1.6.2/animal-sniffer-annotations-1.17.jar new file mode 100644 index 00000000..6ec7a603 Binary files /dev/null and b/lib_worker_1.6.2/animal-sniffer-annotations-1.17.jar differ diff --git a/lib_worker_1.6.2/annotations-4.1.1.4.jar b/lib_worker_1.6.2/annotations-4.1.1.4.jar new file mode 100644 index 00000000..8cbf103f Binary files /dev/null and b/lib_worker_1.6.2/annotations-4.1.1.4.jar differ diff --git a/lib_worker_1.6.2/checker-qual-2.5.2.jar b/lib_worker_1.6.2/checker-qual-2.5.2.jar new file mode 100644 index 00000000..ae4e7f1f Binary files /dev/null and b/lib_worker_1.6.2/checker-qual-2.5.2.jar differ diff --git a/lib_worker_1.6.2/commons-cli-1.4.jar b/lib_worker_1.6.2/commons-cli-1.4.jar new file mode 100644 index 00000000..22deb308 Binary files /dev/null and b/lib_worker_1.6.2/commons-cli-1.4.jar differ diff --git a/lib_worker_1.6.2/commons-lang3-3.9.jar b/lib_worker_1.6.2/commons-lang3-3.9.jar new file mode 100644 index 00000000..0d896939 Binary files /dev/null and b/lib_worker_1.6.2/commons-lang3-3.9.jar differ diff --git a/lib_worker_1.6.2/error_prone_annotations-2.3.2.jar b/lib_worker_1.6.2/error_prone_annotations-2.3.2.jar new file mode 100644 index 00000000..bc2584db Binary files /dev/null and b/lib_worker_1.6.2/error_prone_annotations-2.3.2.jar differ diff --git a/lib_worker_1.6.2/grpc-context-1.20.0.jar b/lib_worker_1.6.2/grpc-context-1.20.0.jar new file mode 100644 index 00000000..1709dbef Binary files /dev/null and b/lib_worker_1.6.2/grpc-context-1.20.0.jar differ diff --git a/lib_worker_1.6.2/grpc-core-1.20.0.jar b/lib_worker_1.6.2/grpc-core-1.20.0.jar new file mode 100644 index 00000000..a44ec185 Binary files /dev/null and b/lib_worker_1.6.2/grpc-core-1.20.0.jar differ diff --git a/lib_worker_1.6.2/grpc-netty-1.20.0.jar b/lib_worker_1.6.2/grpc-netty-1.20.0.jar new file mode 100644 index 00000000..42a96d13 Binary files /dev/null and b/lib_worker_1.6.2/grpc-netty-1.20.0.jar differ diff --git a/lib_worker_1.6.2/grpc-protobuf-1.20.0.jar b/lib_worker_1.6.2/grpc-protobuf-1.20.0.jar new file mode 100644 index 00000000..c0103c11 Binary files /dev/null and b/lib_worker_1.6.2/grpc-protobuf-1.20.0.jar differ diff --git a/lib_worker_1.6.2/grpc-protobuf-lite-1.20.0.jar b/lib_worker_1.6.2/grpc-protobuf-lite-1.20.0.jar new file mode 100644 index 00000000..f96144fc Binary files /dev/null and b/lib_worker_1.6.2/grpc-protobuf-lite-1.20.0.jar differ diff --git a/lib_worker_1.6.2/grpc-stub-1.20.0.jar b/lib_worker_1.6.2/grpc-stub-1.20.0.jar new file mode 100644 index 00000000..958602f4 Binary files /dev/null and b/lib_worker_1.6.2/grpc-stub-1.20.0.jar differ diff --git a/lib_worker_1.6.2/gson-2.8.5.jar b/lib_worker_1.6.2/gson-2.8.5.jar new file mode 100644 index 00000000..0d5baf3f Binary files /dev/null and b/lib_worker_1.6.2/gson-2.8.5.jar differ diff --git a/lib_worker_1.6.2/guava-26.0-jre.jar b/lib_worker_1.6.2/guava-26.0-jre.jar new file mode 100644 index 00000000..cd71a92f Binary files /dev/null and b/lib_worker_1.6.2/guava-26.0-jre.jar differ diff --git a/lib_worker_1.6.2/j2objc-annotations-1.1.jar b/lib_worker_1.6.2/j2objc-annotations-1.1.jar new file mode 100644 index 00000000..4b6f1274 Binary files /dev/null and b/lib_worker_1.6.2/j2objc-annotations-1.1.jar differ diff --git a/lib_worker_1.6.2/javax.annotation-api-1.3.2.jar b/lib_worker_1.6.2/javax.annotation-api-1.3.2.jar new file mode 100644 index 00000000..a8a470a7 Binary files /dev/null and b/lib_worker_1.6.2/javax.annotation-api-1.3.2.jar differ diff --git a/lib_worker_1.6.2/jna-5.3.0.jar b/lib_worker_1.6.2/jna-5.3.0.jar new file mode 100644 index 00000000..4d36ec03 Binary files /dev/null and b/lib_worker_1.6.2/jna-5.3.0.jar differ diff --git a/lib_worker_1.6.2/jna-platform-5.3.0.jar b/lib_worker_1.6.2/jna-platform-5.3.0.jar new file mode 100644 index 00000000..846082d5 Binary files /dev/null and b/lib_worker_1.6.2/jna-platform-5.3.0.jar differ diff --git a/lib_worker_1.6.2/jsr305-3.0.2.jar b/lib_worker_1.6.2/jsr305-3.0.2.jar new file mode 100644 index 00000000..59222d9c Binary files /dev/null and b/lib_worker_1.6.2/jsr305-3.0.2.jar differ diff --git a/lib_worker_1.6.2/netty-buffer-4.1.34.Final.jar b/lib_worker_1.6.2/netty-buffer-4.1.34.Final.jar new file mode 100644 index 00000000..4270aa83 Binary files /dev/null and b/lib_worker_1.6.2/netty-buffer-4.1.34.Final.jar differ diff --git a/lib_worker_1.6.2/netty-codec-4.1.34.Final.jar b/lib_worker_1.6.2/netty-codec-4.1.34.Final.jar new file mode 100644 index 00000000..34b81356 Binary files /dev/null and b/lib_worker_1.6.2/netty-codec-4.1.34.Final.jar differ diff --git a/lib_worker_1.6.2/netty-codec-http-4.1.30.Final.jar b/lib_worker_1.6.2/netty-codec-http-4.1.30.Final.jar new file mode 100644 index 00000000..fdf35355 Binary files /dev/null and b/lib_worker_1.6.2/netty-codec-http-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/netty-codec-http2-4.1.34.Final.jar b/lib_worker_1.6.2/netty-codec-http2-4.1.34.Final.jar new file mode 100644 index 00000000..613eabea Binary files /dev/null and b/lib_worker_1.6.2/netty-codec-http2-4.1.34.Final.jar differ diff --git a/lib_worker_1.6.2/netty-codec-socks-4.1.30.Final.jar b/lib_worker_1.6.2/netty-codec-socks-4.1.30.Final.jar new file mode 100644 index 00000000..513bb346 Binary files /dev/null and b/lib_worker_1.6.2/netty-codec-socks-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/netty-common-4.1.34.Final.jar b/lib_worker_1.6.2/netty-common-4.1.34.Final.jar new file mode 100644 index 00000000..24e8a0e2 Binary files /dev/null and b/lib_worker_1.6.2/netty-common-4.1.34.Final.jar differ diff --git a/lib_worker_1.6.2/netty-handler-4.1.30.Final.jar b/lib_worker_1.6.2/netty-handler-4.1.30.Final.jar new file mode 100644 index 00000000..4caf92f6 Binary files /dev/null and b/lib_worker_1.6.2/netty-handler-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/netty-handler-proxy-4.1.30.Final.jar b/lib_worker_1.6.2/netty-handler-proxy-4.1.30.Final.jar new file mode 100644 index 00000000..4adcdbe3 Binary files /dev/null and b/lib_worker_1.6.2/netty-handler-proxy-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/netty-resolver-4.1.30.Final.jar b/lib_worker_1.6.2/netty-resolver-4.1.30.Final.jar new file mode 100644 index 00000000..e140d87d Binary files /dev/null and b/lib_worker_1.6.2/netty-resolver-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/netty-transport-4.1.30.Final.jar b/lib_worker_1.6.2/netty-transport-4.1.30.Final.jar new file mode 100644 index 00000000..0e4ca601 Binary files /dev/null and b/lib_worker_1.6.2/netty-transport-4.1.30.Final.jar differ diff --git a/lib_worker_1.6.2/opencensus-api-0.19.2.jar b/lib_worker_1.6.2/opencensus-api-0.19.2.jar new file mode 100644 index 00000000..c9427f9c Binary files /dev/null and b/lib_worker_1.6.2/opencensus-api-0.19.2.jar differ diff --git a/lib_worker_1.6.2/opencensus-contrib-grpc-metrics-0.19.2.jar b/lib_worker_1.6.2/opencensus-contrib-grpc-metrics-0.19.2.jar new file mode 100644 index 00000000..dfb7080b Binary files /dev/null and b/lib_worker_1.6.2/opencensus-contrib-grpc-metrics-0.19.2.jar differ diff --git a/lib_worker_1.6.2/proto-google-common-protos-1.12.0.jar b/lib_worker_1.6.2/proto-google-common-protos-1.12.0.jar new file mode 100644 index 00000000..9dab1cd4 Binary files /dev/null and b/lib_worker_1.6.2/proto-google-common-protos-1.12.0.jar differ diff --git a/lib_worker_1.6.2/protobuf-java-3.7.1.jar b/lib_worker_1.6.2/protobuf-java-3.7.1.jar new file mode 100644 index 00000000..40761f39 Binary files /dev/null and b/lib_worker_1.6.2/protobuf-java-3.7.1.jar differ diff --git a/package-pipeline.ps1 b/package-pipeline.ps1 new file mode 100644 index 00000000..5a442ca3 --- /dev/null +++ b/package-pipeline.ps1 @@ -0,0 +1,29 @@ +param ( + [string]$buildNumber = $env:APPVEYOR_BUILD_NUMBER +) + +# A function that checks exit codes and fails script if an error is found +function StopOnFailedExecution { + if ($LastExitCode) + { + exit $LastExitCode + } +} +Write-Host "Building azure-functions-java-worker" +cmd.exe /c '.\mvnBuild.bat' +StopOnFailedExecution + +Write-Host "Creating nuget package Microsoft.Azure.Functions.JavaWorker" +Write-Host "buildNumber: " $buildNumber +Get-Command nuget +StopOnFailedExecution +remove-item pkg -Recurse -ErrorAction Ignore +mkdir pkg +Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar','*tests.jar' | %{ Copy-Item $_.FullName .\pkg\azure-functions-java-worker.jar } +StopOnFailedExecution +copy-item ./worker.config.json pkg +copy-item ./tools/AzureFunctionsJavaWorker.nuspec pkg/ +Copy-Item ".\lib_worker_1.6.2" pkg\lib -Recurse +set-location pkg +nuget pack -Properties version=$buildNumber +set-location .. \ No newline at end of file diff --git a/package.ps1 b/package.ps1 index bd353fae..bec821d4 100644 --- a/package.ps1 +++ b/package.ps1 @@ -23,6 +23,7 @@ Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar' | %{ Cop StopOnFailedExecution copy-item ./worker.config.json pkg copy-item ./tools/AzureFunctionsJavaWorker.nuspec pkg/ +Copy-Item ".\lib_worker_1.6.2" pkg\lib -Recurse set-location pkg nuget pack -Properties version=$buildNumber set-location .. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 78e4a3a5..6df6e13e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.microsoft.azure.functions azure-functions-java-worker - 1.6.2 + 1.7.1 jar com.microsoft.maven @@ -174,7 +174,7 @@ maven-shade-plugin - 3.2.0 + 3.2.4 package @@ -184,7 +184,7 @@ + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> com.microsoft.azure.functions.worker.Application ${project.name} @@ -192,6 +192,7 @@ ${project.organization.name} + @@ -203,6 +204,56 @@ + + + com.google + com.microsoft.azure.functions.shaded.com.google + + + com.sun + com.microsoft.azure.functions.shaded.com.sun + + + android + com.microsoft.azure.functions.shaded.android + + + google + com.microsoft.azure.functions.shaded.google + + + identity + com.microsoft.azure.functions.shaded.identity + + + shared + com.microsoft.azure.functions.shaded.shared + + + org + com.microsoft.azure.functions.shaded.org + + + io.netty + com.microsoft.azure.functions.shaded.io.netty + + + io.perfmark + com.microsoft.azure.functions.shaded.io.perfmark + + + io.grpc + com.microsoft.azure.functions.shaded.io.grpc + + + javax.annotation + com.microsoft.azure.functions.shaded.javax.annotation + + + io.opencensus + com.microsoft.azure.functions.shaded.io.opencensus + + diff --git a/setup-tests-pipeline.ps1 b/setup-tests-pipeline.ps1 index 9758553b..bbbec55e 100644 --- a/setup-tests-pipeline.ps1 +++ b/setup-tests-pipeline.ps1 @@ -36,4 +36,4 @@ if(!$skipCliDownload) Write-Host "Copying azure-functions-java-worker to Functions Host workers directory...." Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar','*tests.jar' | %{ Copy-Item $_.FullName ".\Azure.Functions.Cli\workers\java\azure-functions-java-worker.jar" } Copy-Item ".\worker.config.json" ".\Azure.Functions.Cli\workers\java" - +Copy-Item ".\lib_worker_1.6.2" ".\Azure.Functions.Cli\workers\java\lib" -Recurse diff --git a/setup-tests.ps1 b/setup-tests.ps1 index 78e60ca9..6dc3dc00 100644 --- a/setup-tests.ps1 +++ b/setup-tests.ps1 @@ -44,6 +44,7 @@ if(!$skipCliDownload) Write-Host "Copying azure-functions-java-worker to Functions Host workers directory...." Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar','*tests.jar' | %{ Copy-Item $_.FullName ".\Azure.Functions.Cli\workers\java\azure-functions-java-worker.jar" } Copy-Item ".\worker.config.json" ".\Azure.Functions.Cli\workers\java" +Copy-Item ".\lib_worker_1.6.2" ".\Azure.Functions.Cli\workers\java\lib" -Recurse Write-Host "Building endtoendtests...." $Env:Path = $Env:Path+";$currDir\Azure.Functions.Cli" diff --git a/src/main/java/com/microsoft/azure/functions/worker/Constants.java b/src/main/java/com/microsoft/azure/functions/worker/Constants.java index 8be2597e..4e78448e 100644 --- a/src/main/java/com/microsoft/azure/functions/worker/Constants.java +++ b/src/main/java/com/microsoft/azure/functions/worker/Constants.java @@ -6,4 +6,6 @@ public final class Constants { private Constants(){} public final static String TRIGGER_METADATA_DOLLAR_REQUEST_KEY = "$request"; + public final static String FUNCTIONS_WORKER_DIRECTORY = "FUNCTIONS_WORKER_DIRECTORY"; + public final static String FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS = "FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS"; } diff --git a/src/main/java/com/microsoft/azure/functions/worker/Helper.java b/src/main/java/com/microsoft/azure/functions/worker/Helper.java new file mode 100644 index 00000000..08d05e48 --- /dev/null +++ b/src/main/java/com/microsoft/azure/functions/worker/Helper.java @@ -0,0 +1,9 @@ +package com.microsoft.azure.functions.worker; + +public class Helper { + + public static boolean isLoadAppLibsFirst() { + String javaReverseLibLoading = System.getenv(Constants.FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS); + return Util.isTrue(javaReverseLibLoading); + } +} diff --git a/src/main/java/com/microsoft/azure/functions/worker/Util.java b/src/main/java/com/microsoft/azure/functions/worker/Util.java new file mode 100644 index 00000000..8f7206d1 --- /dev/null +++ b/src/main/java/com/microsoft/azure/functions/worker/Util.java @@ -0,0 +1,10 @@ +package com.microsoft.azure.functions.worker; + +public class Util { + public static boolean isTrue(String value) { + if(value != null && (value.toLowerCase().equals("true") || value.toLowerCase().equals("1"))) { + return true; + } + return false; + } +} 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 9ba56372..3e532691 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 @@ -1,6 +1,8 @@ package com.microsoft.azure.functions.worker.broker; import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.util.*; @@ -8,10 +10,13 @@ import com.microsoft.azure.functions.rpc.messages.*; import com.microsoft.azure.functions.worker.Constants; +import com.microsoft.azure.functions.worker.Helper; +import com.microsoft.azure.functions.worker.Util; import com.microsoft.azure.functions.worker.binding.BindingDataStore; import com.microsoft.azure.functions.worker.description.FunctionMethodDescriptor; import com.microsoft.azure.functions.worker.reflect.ClassLoaderProvider; +import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -87,14 +92,46 @@ private void addSearchPathsToClassLoader(FunctionMethodDescriptor function) thro function.getLibDirectory().ifPresent(d -> registerWithClassLoaderProvider(d)); } - private void registerWithClassLoaderProvider(File libDirectory) { + void registerWithClassLoaderProvider(File libDirectory) { try { - classLoaderProvider.addDirectory(libDirectory); + if(SystemUtils.IS_JAVA_1_8) { + String workerLibPath = System.getenv(Constants.FUNCTIONS_WORKER_DIRECTORY) + "/lib"; + File workerLib = new File(workerLibPath); + verifyLibrariesExist (workerLib, workerLibPath); + + if(Helper.isLoadAppLibsFirst()) { + // load client app jars first. + classLoaderProvider.addDirectory(libDirectory); + classLoaderProvider.addDirectory(workerLib); + } else { + // Default load worker jars first. + classLoaderProvider.addDirectory(workerLib); + classLoaderProvider.addDirectory(libDirectory); + } + } else { + classLoaderProvider.addDirectory(libDirectory); + } } catch (Exception ex) { ExceptionUtils.rethrow(ex); } } + void verifyLibrariesExist (File workerLib, String workerLibPath) throws FileNotFoundException{ + if(!workerLib.exists()) { + throw new FileNotFoundException("Error loading worker jars, from path: " + workerLibPath); + } else { + File[] jarFiles = workerLib.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isFile() && file.getName().endsWith(".jar"); + } + }); + if(jarFiles.length == 0) { + throw new FileNotFoundException("Error loading worker jars, from path: " + workerLibPath + ". Jars size is zero"); + } + } + } + private final Map> methods; private final ClassLoaderProvider classLoaderProvider; } diff --git a/src/test/java/com/microsoft/azure/functions/worker/UtilTests.java b/src/test/java/com/microsoft/azure/functions/worker/UtilTests.java new file mode 100644 index 00000000..deb19c32 --- /dev/null +++ b/src/test/java/com/microsoft/azure/functions/worker/UtilTests.java @@ -0,0 +1,24 @@ +package com.microsoft.azure.functions.worker; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class UtilTests { + + @Test + public void isTrueNull() { + assertFalse(Util.isTrue(null)); + } + + @Test + public void isTrueEmptyString() { + assertFalse(Util.isTrue("")); + } + + @Test + public void isTrueValueTrue() { + assertTrue(Util.isTrue("True")); + } +} diff --git a/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaFunctionBrokerTest.java b/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java similarity index 91% rename from src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaFunctionBrokerTest.java rename to src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java index 1422c56e..a66b9863 100644 --- a/src/test/java/com/microsoft/azure/functions/worker/broker/tests/JavaFunctionBrokerTest.java +++ b/src/test/java/com/microsoft/azure/functions/worker/broker/JavaFunctionBrokerTest.java @@ -1,4 +1,4 @@ -package com.microsoft.azure.functions.worker.broker.tests; +package com.microsoft.azure.functions.worker.broker; import com.microsoft.azure.functions.rpc.messages.InvocationRequest; import com.microsoft.azure.functions.rpc.messages.ParameterBinding; @@ -7,9 +7,13 @@ import com.microsoft.azure.functions.worker.reflect.DefaultClassLoaderProvider; import mockit.*; import org.junit.Test; + +import java.io.File; +import java.io.FileNotFoundException; import java.util.*; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class JavaFunctionBrokerTest { @@ -105,4 +109,18 @@ public void getTriggerMetadataMap_ignored( // In case of non-http request, it will not modify the triggerMetadata assertEquals(expectedCount, actualTriggerMetadata.size()); } + + @Test(expected = FileNotFoundException.class) + public void checkLibFolderNoWorkerLib() throws Exception { + JavaFunctionBroker broker = new JavaFunctionBroker(null); + broker.verifyLibrariesExist (new File(""), null); + } + + @Test(expected = FileNotFoundException.class) + public void checkLibFolderNoJarsInLib() throws Exception { + JavaFunctionBroker broker = new JavaFunctionBroker(null); + String path = "../"; + File file = new File(path); + broker.verifyLibrariesExist (file, path); + } }