Serverless Java Apps with VS Code

Serverless, as indicated by its name, allows you to execute your code in an environment without having to first create a VM or publish a web application.

This tutorial guides you through creating a serverless function project and deploying to Azure with Visual Studio Code and the Azure Functions extension. You'll be able to test the function locally and then deploy it to Azure Functions. When you're done, you'll have a HTTP-triggered function app running in Azure.

Prerequisites

To develop Azure Functions with Java, you'll need the following tools installed:

Important: The JAVA_HOME environment variable must be set to the install location of the JDK to complete this tutorial.

Install the Azure Functions extension

The Azure Functions extension provides an easy way for you to manage your serverless functions with Azure. It supports both Java and JavaScript Functions with features including:

  • Create new project.
  • Create new Function from template.
  • Debug Function projects locally.
  • View Azure Function Apps.
  • Create, delete, start, stop and restart Azure Function Apps.
  • JSON Intellisense for function.json, host.json and proxies.json files.

In this tutorial, we will leverage this extension to create the serverless function. For a more command line Maven-centric experience, you can also check out the Maven Functions Tutorial. The Java support of this extension leverages a lot from the Maven Plugin for Azure Functions.

To install the Azure Functions extension, open the Extensions view (⇧⌘X (Windows, Linux Ctrl+Shift+X)) and search for azure functions to filter the results. Select the Microsoft Azure Functions extension.

Generate a new Functions project

Once you've installed the Azure Functions extension, you can easily create a new project by:

  1. Click Create New Project button on the AZURE FUNCTIONS Explorer view.
  2. Select target folder.
  3. Select Java the target language.
  4. Fill in the parameters.

The extension uses Maven archetypes to create the function project in the folder you specified.

Create Functions Project

Within the created project, there's a simple HTTP triggered 'Hello World' Function which reads the input from HTTP query string or body and returns it back immediately.

/**
 * Azure Functions with HTTP Trigger.
 */
public class Function {
    @FunctionName("hello")
    public HttpResponseMessage<String> httpHandler(
            @HttpTrigger(name = "req", methods = {"get", "post"}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context
    ) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        String query = request.getQueryParameters().get("name");
        String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponse(400, "Please pass a name on the query string or in the request body");
        } else {
            return request.createResponse(200, "Hello, " + name);
        }
    }
}

Install the Azure Functions Core Tools

Note: This step is optional and only required to locally run and debug your Java Functions source code.

The Azure Functions Core Tools 2.0 provides a local development environment for writing, running, and debugging Azure Functions. The installation package for v2 is a self-contained cross-platform package.

Windows

npm i -g azure-functions-core-tools@core --unsafe-perm true

macOS

Homebew:

brew tap azure/functions
brew install azure-functions-core-tools

Linux

Ubuntu/Debian

  1. Register the Microsoft Product key as trusted.
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
  1. Add source

Ubuntu 16.04 / Linux Mint 18

sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-get update
  1. Install
sudo apt install azure-functions-core-tools

You can learn more by reading the Code and test Azure Functions locally How-to guide.

NOTE: npm can be used on all platforms. On Unix platforms, you may need to specify --unsafe-perm if you are running npm with sudo. This is necessary due to npm's post install script behavior.

NOTE: If you're running the v2 on Windows, Linux, or macOS, make sure to enable the preview runtime in function app settings, otherwise you may not see the same results as running locally.

Run and debug the function locally

Once the function is created, press F5 to start the function. Behind the scene, we've configured the launch.json debugger configuration file (created under the project .vscode folder) to build the functions project and then start the local runtime provided by Azure Functions Core Tools 2.0. If you would like to debug your function, set a break point (F9) and then send a request to trigger the HTTP function.

curl -w '\n' -d LocalFunction http://localhost:7071/api/hello

You should see:

Hello LocalFunction!

Debug Functions Project

Use Ctrl+C in the terminal to stop the function code.

Deploy the function to Azure

If you don't have an Azure subscription, you can sign up for a free Azure account.

Create your free Azure account

The deploy process leverages the Azure Account extension (installed along with the Azure Functions extension as an dependency) and you need to sign in with your Azure subscription. If you do not have an Azure subscription, sign up today for a free 30 day account and get $200 in Azure Credits to try out any combination of Azure services.

To log into Azure, run Azure: Sign In from the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)). You can then sign into your account using the Device Login flow. Click on Copy & Open to open your default browser.

Azure sign in code

Paste in the access code and continue the sign in process.

Azure Device Login

After signing in, click Deploy to Function App button, select the folder of the project you would like to deploy from, and follow the prompts to configure your function project.

Deploy Functions

Once the function is deployed, test the function app running on Azure using curl:

curl -w '\n' https://fabrikam-function-20170920120101928.azurewebsites.net/api/hello -d AzureFunctions

You should see:

Hello AzureFunctions!

Add additional functions to the project

The extension also supports adding new functions to the existing project:

  1. Click Add Function button on the AZURE FUNCTIONS Explorer bar.
  2. Select project folder.
  3. Select function type.
  4. Fill in the parameters for this function type.

Add Functions

Remote debugging

Although the local core tool from Azure Functions is running the same code as in the cloud, sometimes environment differences may cause your function to behave differently. Using remote debugging, you can troubleshoot those issues.

There is a special Remote Debugging Tool to help you set up the remote debugging session which you can install it via npm:

npm install -g cloud-debug-tools

Once it's installed, run the tool to attach to the running Function on Azure

dbgproxy fabrikam-function-20170920120101928.azurewebsites.net

The tool depends on the Azure CLI to fetch your credentials so make sure you've logged in with the same account.

az login

The tool will then figure out the rest for you. Once it's connected to the running Function, add a new debugging configuration to attach to the local port opened by it.

{
    "name": "Attach to Azure Functions on Cloud",
    "type": "java",
    "request": "attach",
    "hostName": "localhost",
    "port": 8898
}

Now you can set a break point and attach to your cloud function using VS Code. When you launch a debug session with the above configuration, you can step through it just like you did locally. It's also useful if you don't have .Net Core and the Azure Functions CLI core tool installed on your local environment and you want to jump start within the cloud directly.

Next steps

You have created a Java function app with a simple HTTP trigger and deployed it to Azure Functions.