DEV Community

Tsuyoshi Ushio
Tsuyoshi Ushio

Posted on

Debugging Java Language Worker on Azure Functions

If you want to contribute Java Language worker, how to debug it? It works with Azure Functions Host.

There is three player for this debug story.

Alt Text

Architecture

1. Azure Functions Host (C#)

The main process of the Azure Functions execution. Under the food, it uses WebJobsSDK.

2. Binding Extensions (C# + wrapper)

Azure functions has a several Triggers and bindings. It will receive an event by the various measure. Http, Queue, Kafka, EventHubs, CosmosDB ... and so on. It also outputs messages. It is written by C#. Language implementation is an wrapper of the C# implementation.

3. Java Language Worker (Java)

Java Language Worker is a worker process. Except for C# precompile implementation, Azure Functions host delegate the function execution to each language workers via gRPC.

4. Azure Functions Java Library (Java)

That is mainly the definition of annotation that is used by the Binding Extensions wrapper. The library is referenced by User's Azure Functions, Java Language Worker, and Azure Functions Maven Plugin.

5. Application Insights Agent (Java)

It is injected with the Java Language Worker as an agent. It is automatically track the telemetries with correlation without changing any code. The automated dependency tracking is limited for some libraries. Please refer to it on this article.

6. Azure Functions (Java)

Azure Functions that customers write. The Language worker class loader load the functions by the annotations.

How to debug it?

Since there is a lot of players, how can I debug the Java Worker part? We can easily debug the Azure Functions part. However, Java Worker is started by the Azure Functions Host.

Create an Azure Functions

For debugging the Java Language Worker, we need create a function to execute it. Please refer to Quickstart: Create a function in Azure that responds to HTTP requests

One point for the debugging is, how to manage the Binding extensions. Usually, we use Extension bundles. So we don't need to install the Bindings by setting the host.json. It will automatically install the extensions.

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

However, the local debug scenario, you might need to install the extension by your self. You need to have extension.csproj file under the, target/azure-functions/<YOUR_FUNCTION_APP_NAME> directory.

Install extension

Alt Text

This code is a sample for EventHubs

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <WarningsAsErrors></WarningsAsErrors>
    <DefaultItemExcludes>**</DefaultItemExcludes>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="4.1.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="1.1.7" />
  </ItemGroup>
</Project>

Then go to the target/azure-functions/<FUNCTION_APP_NAME> dir.

PS > mvn clean package
PS > cp extension.csproj target\azure-functions\fabrikam-functions
PS > cd target\azure-functions\fabrikam-functions
PS > func extension install

You will see the bin directory that contains DLL files for the extensions. The DLL is libraries of the Extension.

Now ready to configure Azure Functions Host.

Configure Azure Functions Host for Java Worker Debugging

WebJobs.Script.WebHost as startup

Clone the Azure Functions Host. Then open Visual Studio and make WebJobs.Script.WebHost as startup project.

Alt Text

Configure Environment Variables

Right click WebJobs.Script.WebHost > Properties > Debug. Configure the environment variables.

Alt Text

Name Value (sample) Description
AzureWebJobsScriptRoot C:\Users\tsushi\Code\java\azure-functions-samples\EventHubs\target\azure-functions\fabrikam-functions-20200814172147278 Point to the azure functions function app directory
ASPNETCORE_ENVIRONMENT Development Mode for AspNetCore
AZURE_FUNCTIONS_ENVIRONMENT Development Mode for Azure Functions Host
AzureWebJobsDashboard UseDevelopmentStorage=true Connection string of Storage Account or Storage Emulator for the functions host dashboard.
AzureWebJobsStorage UseDevelopmentStorage=true Connection string of Storage Account or Storage Emulator for the functions host.
FUNCTIONS_WORKER_RUNTIME java Worker Runtime
languageWorkers:java:arguments -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 Environment Variables for debugging

Also you need to add AppSettings that your functions need.
You might wondering why AZURE_FUNCTIONS_ENVIRONMENT and ASPNETCORE_ENVIRONMENT.

You'll want to use AZURE_FUNCTIONS_ENVIRONMENT. The Functions runtime that powers a Function app on Azure is the WebHost project in this repo. As the host is initializing, it looks for the AZURE_FUNCTIONS_ENVIRONMENT app setting (as EnvironmentSettingNames.EnvironmentNameKey) and passes it to the IWebHostBuilder. Using only ASPNETCORE_ENVIRONMENT can lead to desired behavior changes and telemetry being missed.

Update JavaWorker

If you modify your code on the Java worker, you need to build it and package it on the Java Worker's cloned repo.

PS > mvn clean package

You will find azure-functions-java-worker-<VERSION>.jar. Copy the jar file to the WebJobs.Script.WebHost\bin\Debug\netcoreapp3.1\workers\java on the Azure Functions Host project.

Now ready to debug. hit F5. Then debugging starts. One tips is, if you choose IIS Express you can not see a log. Choose 1WebJobs.Script.WebHost` instead.

Alt Text

Attach from an IntelliJ

Follow Debugging Azure Functions Host and Java Worker

Create a remote debugging.

Alt Text

Just click start the debugging on the IntelliJ. It attach to the 5005 port that is the Java worker. Just send an request http://localhost:5000/api/YOUR_FUNCTIONS_NAME. or sending queues for triggering your Azure Functions.

It works!
Alt Text

Resource

Top comments (0)