GithubHelp home page GithubHelp logo

mattwelke / apache-openwhisk-runtime-java-11 Goto Github PK

View Code? Open in Web Editor NEW
1.0 3.0 0.0 304 KB

A custom Apache OpenWhisk runtime for Java to add support for Java 11+. Not affiliated with the Apache Software Foundation.

License: Apache License 2.0

Dockerfile 5.56% Shell 2.75% Java 91.69%
openwhisk openwhisk-runtime java serverless

apache-openwhisk-runtime-java-11's Introduction

apache-openwhisk-runtime-java

A Java 11 runtime for Apache OpenWhisk. Solves the problem in apache/openwhisk-runtime-java#82 (that modern Java doesn't allow environment variables to be mutated at runtime) by using a second user action parameter for the "OpenWhisk variables" instead of adding them as environment variables prepended with __OW_.

Also, removes the user action's dependency on Gson by using Java's native map data structure (java.util.Map) as the parameter types and return type.

Put together, user actions look like this:

import java.util.HashMap;
import java.util.Map;

public class Function {
    public static Map<String, Object> main(Map<String, Object> params, Map<String, Object> owVars) {

        System.out.println("Runtime version: " + Runtime.version());

        printMap(params, "Params");
        printMap(owVars, "OpenWhisk variables");

        var output = new HashMap<String, Object>();
        output.put("hello", "world");
        output.put("answer", 42);

        return output;
    }

    private static void printMap(Map<String, Object> map, String mapName) {
        System.out.println(mapName + " entries:");
        for (var entry : map.entrySet()) {            
            System.out.println("Key: " + entry.getKey() + " | Value: " + entry.getValue());
        }
    }
}

Examples in logs from IBM Cloud Functions:

Image of IBM Cloud Functions activation with Java 11 runtime

(cold starts where a node already has the image take about 350 ms)

They are deployed as Docker actions so that they can use this custom runtime:

ibmcloud fn action update <fn_name> function.jar \
  --docker mwelke/openwhisk-runtime-java11:18 \
  --main Function \
  --web true

Local development

For now, neither Maven nor Gradle are used as a build system. The VS Code Java new project output was used as a template.

Building

Run script/build.sh <docker_hub_id|registry> <new_version> to compile the Java source code and build the Docker image with the compiled class files. Then, run a docker push command to push the built image to a registry if you want to use it with a public cloud Apache OpenWhisk platform such as IBM Cloud Functions.

Note that adoptopenjdk:11.0.11_9-jre-openj9-0.26.0 is used as the base Docker image so that the JDK, which isn't needed to run the user action code, isn't included in the final runtime image.

Updating dependencies

Because it's a custom build system, and classpaths must be specified in build steps, you must replace the reference to gson-2.8.7.jar with a new version if Gson is ever updated and add references to new JAR files if new dependencies are ever added, in the following files:

  • scripts/build.sh (javac command)
  • Dockerfile (CMD directive at the bottom)

IDEs

VS Code configuration is checked into the repository in .vscode.

To do

  • In the future, builds will be automated and a multi-stage Docker build will be used so that developers' machines don't need the right build environment to do a build. A JDK image will be used as base for the first stage (aka build stage) and the JRE image will be used as the base for the final stage.
  • Java 16 runtime (which would stop being maintained when Java 16 reaches EOL, but Java 11 would continue being maintained until its EOL).
  • Java 8 (to backport new user action contract with java.util.Map types instead of Gson)

Concerning ActionLoop proxy

See https://github.com/apache/openwhisk/blob/master/docs/actions-actionloop.md for background info.

Using ActionLoop proxy would have made it too difficult for me to create this custom runtime because I lack experience with Gradle (needed to understand the complex build system) and Python (needed for the compile script you're expected to create). Therefore, to reduce the barrier to entry to create the custom runtime, I used the original runtime that just used an HTTP server as reference, since I'm already familiar with HTTP server apps and I could get by without needing to use Gradle.

Furthermore, it isn't clear that the ActionLoop proxy protocol itself improves performance over using an HTTP server in the runtime's native language. For the Node.js runtime, it was found to not improve performance (https://openwhisk-team.slack.com/archives/C3TPCAQG1/p1607833804403300?thread_ts=1607829152.403100&cid=C3TPCAQG1). This may be due to the fact that the Node.js runtime stores the user action code in memory instead of writing it to disk:

Node.js runtime init:

https://github.com/apache/openwhisk-runtime-nodejs/blob/master/core/nodejsActionBase/runner.js

class NodeActionRunner {

    constructor(handler) {
        this.userScriptMain = handler;
    }
// more code

The Ruby runtime was found to be improved by using ActionLoop proxy. There, the new Go code appears to store the user action code more efficiently than the original Ruby approach, which wrote the user action code to disk:

Ruby runtime init before ActionLoop:

https://github.com/apache/openwhisk-runtime-ruby/blob/master/core/ruby2.5Action/rackapp/init.rb

File.write TMP_ZIP, Base64.decode64(code)

Ruby runtime init after ActionLoop (delegated to Go runtime):

https://github.com/apache/openwhisk-runtime-go/blob/master/openwhisk/initHandler.go

buf, err = base64.StdEncoding.DecodeString(request.Value.Code)
// more code
_, err = ap.ExtractAndCompile(&buf, main)

If this runtime is maintained longtime outside of the Apache Software Foundation, as a 3rd party runtime instead of an official runtime, the ActionLoop proxy approach will be investigated further before it is used.

Disclaimers

This is a 3rd party runtime and this repository is not affiliated with the Apache Software Foundation. Some code was reused without changes from the https://github.com/apache/openwhisk-runtime-java repository, in which case the package hierarchy and Apache licence headers were retained on those files.

All code here is published under Apache License 2.0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.