{"id":14987804,"url":"https://github.com/apache/openwhisk-runtime-java","last_synced_at":"2025-07-20T04:33:00.690Z","repository":{"id":39707169,"uuid":"104973620","full_name":"apache/openwhisk-runtime-java","owner":"apache","description":"Apache OpenWhisk Runtime Java supports Apache OpenWhisk functions written in Java and other JVM-hosted languages","archived":false,"fork":false,"pushed_at":"2024-09-24T13:11:35.000Z","size":3261,"stargazers_count":45,"open_issues_count":22,"forks_count":63,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-07-15T04:14:01.430Z","etag":null,"topics":["apache","cloud","docker","faas","functions","functions-as-a-service","java","jvm","openwhisk","openwhisk-runtime","serverless","serverless-architectures","serverless-functions"],"latest_commit_sha":null,"homepage":"https://openwhisk.apache.org/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apache.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-27T04:55:50.000Z","updated_at":"2025-06-18T10:58:47.000Z","dependencies_parsed_at":"2024-06-07T14:42:18.220Z","dependency_job_id":"28ac357f-bb3c-4a8a-8693-35fcd69f7ac6","html_url":"https://github.com/apache/openwhisk-runtime-java","commit_stats":{"total_commits":831,"total_committers":73,"mean_commits":"11.383561643835616","dds":0.7990373044524669,"last_synced_commit":"f2f67db117c6cd3695493439c35e8aa39391d2d5"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/apache/openwhisk-runtime-java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fopenwhisk-runtime-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fopenwhisk-runtime-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fopenwhisk-runtime-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fopenwhisk-runtime-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apache","download_url":"https://codeload.github.com/apache/openwhisk-runtime-java/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fopenwhisk-runtime-java/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265934168,"owners_count":23852084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache","cloud","docker","faas","functions","functions-as-a-service","java","jvm","openwhisk","openwhisk-runtime","serverless","serverless-architectures","serverless-functions"],"created_at":"2024-09-24T14:15:28.880Z","updated_at":"2025-07-20T04:33:00.666Z","avatar_url":"https://github.com/apache.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n--\u003e\n\n# Apache OpenWhisk runtimes for java\n\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)\n[![Continuous Integration](https://github.com/apache/openwhisk-runtime-java/actions/workflows/ci.yaml/badge.svg)](https://github.com/apache/openwhisk-runtime-java/actions/workflows/ci.yaml)\n\n## Changelogs\n- [Java 8 CHANGELOG.md](core/java8/CHANGELOG.md)\n\n\n## Quick Java Action\nA Java action is a Java program with a method called `main` that has the exact signature as follows:\n```java\npublic static com.google.gson.JsonObject main(com.google.gson.JsonObject);\n```\n\nFor example, create a Java file called `Hello.java` with the following content:\n\n```java\nimport com.google.gson.JsonObject;\n\npublic class Hello {\n    public static JsonObject main(JsonObject args) {\n        String name = \"stranger\";\n        if (args.has(\"name\"))\n            name = args.getAsJsonPrimitive(\"name\").getAsString();\n        JsonObject response = new JsonObject();\n        response.addProperty(\"greeting\", \"Hello \" + name + \"!\");\n        return response;\n    }\n}\n```\nIn order to compile, test and archive Java files, you must have a [JDK 8](http://openjdk.java.net/install/) installed locally.\n\nThen, compile `Hello.java` into a JAR file `hello.jar` as follows:\n```\njavac Hello.java\n```\n```\njar cvf hello.jar Hello.class\n```\n\n**Note:** [google-gson](https://github.com/google/gson) must exist in your Java CLASSPATH when compiling the Java file.\n\nYou need to specify the name of the main class using `--main`. An eligible main\nclass is one that implements a static `main` method as described above. If the\nclass is not in the default package, use the Java fully-qualified class name,\ne.g., `--main com.example.MyMain`.\n\nIf needed you can also customize the method name of your Java action. This\ncan be done by specifying the Java fully-qualified method name of your action,\ne.q., `--main com.example.MyMain#methodName`\n\nNot only support return JsonObject but also support return JsonArray, the main function would be:\n\n```java\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\n\npublic class HelloArray {\n    public static JsonArray main(JsonObject args) {\n        JsonArray jsonArray = new JsonArray();\n        jsonArray.add(\"a\");\n        jsonArray.add(\"b\");\n        return jsonArray;\n    }\n}\n```\n\nAnd support array result for sequence action as well, the first action's array result can be used as next action's input parameter.\n\nSo the function would be:\n\n```java\nimport com.google.gson.JsonArray;\n\npublic class Sort {\n    public static JsonArray main(JsonArray args) {\n        return args;\n    }\n}\n```\n\n### Create the Java Action\nTo use as a docker action:\n```\nwsk action update helloJava hello.jar --main Hello --docker openwhisk/java8action\n```\nThis works on any deployment of Apache OpenWhisk\n\nTo use on a deployment of OpenWhisk that contains the runtime as a kind:\n```\nwsk action update helloJava hello.jar --main Hello --kind java:8\n```\n\n### Invoke the Java Action\nAction invocation is the same for Java actions as it is for Swift and JavaScript actions:\n\n```\nwsk action invoke --result helloJava --param name World\n```\n\n```json\n  {\n      \"greeting\": \"Hello World!\"\n  }\n```\n\n## Local development\n\n### Pre-requisites\n- Gradle\n- Docker Desktop (local builds)\n\n### Build  and Push image to a local Docker registry\n\n1. Start Docker Desktop (i.e., Docker daemon)\n\n2. Build the Docker runtime image locally using Gradle:\n```\n./gradlew core:java8:distDocker\n```\nThis will produce the image `whisk/java8action` and push it to the local Docker Desktop registry with the `latest` tag.\n\n3. Verify the image was registered:\n```\n$ docker images whisk/*\nREPOSITORY           TAG     IMAGE ID            CREATED             SIZE\nwhisk/java8action    latest  35f90453905a        7 minutes ago       521MB\n```\n\n### Build and Push image to a remote Docker registry\n\nBuild the Docker runtime image locally using Gradle supplying the image Prefix and Registry domain (default port):\n```\ndocker login\n./gradlew core:java8:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io\n```\n\n## Deploying the Java runtime image to OpenWhisk\n\nDeploy OpenWhisk using ansible environment that contains the kind `java:8`\nAssuming you have OpenWhisk already deployed locally and `OPENWHISK_HOME` pointing to root directory of OpenWhisk core repository.\n\nSet `ROOTDIR` to the root directory of this repository.\n\nRedeploy OpenWhisk\n```\ncd $OPENWHISK_HOME/ansible\nANSIBLE_CMD=\"ansible-playbook -i ${ROOTDIR}/ansible/environments/local\"\n$ANSIBLE_CMD setup.yml\n$ANSIBLE_CMD couchdb.yml\n$ANSIBLE_CMD initdb.yml\n$ANSIBLE_CMD wipe.yml\n$ANSIBLE_CMD openwhisk.yml\n```\n\nOr you can use `wskdev` and create a soft link to the target ansible environment, for example:\n```\nln -s ${ROOTDIR}/ansible/environments/local ${OPENWHISK_HOME}/ansible/environments/local-java\nwskdev fresh -t local-java\n```\n\n### Testing\nInstall dependencies from the root directory on $OPENWHISK_HOME repository\n```\npushd $OPENWHISK_HOME\n./gradlew install\npopd $OPENWHISK_HOME\n```\n\nUsing gradle to run all tests\n```\n./gradlew :tests:test\n```\nUsing gradle to run some tests\n```\n./gradlew :tests:test --tests *ActionContainerTests*\n```\nUsing IntelliJ:\n- Import project as gradle project.\n- Make sure working directory is root of the project/repo\n\n#### Using container image to test\nTo use as docker action push to your own dockerhub account\n```\ndocker tag whisk/java8action $user_prefix/java8action\ndocker push $user_prefix/java8action\n```\nThen create the action using your the image from dockerhub\n```\nwsk action update helloJava hello.jar --main Hello --docker $user_prefix/java8action\n```\nThe `$user_prefix` is usually your dockerhub user id.\n\n---\n\n# Troubleshooting\n\n### Gradle build fails with \"Too many files open\"\n\nThis may occur on MacOS as the default maximum # of file handles per session is `256`.  The gradle build requires many more and is unable to open more files (e.g., `java.io.FileNotFoundException`).  For example, you may see something like:\n\n```\n\u003e java.io.FileNotFoundException: /Users/XXX/.gradle/caches/4.6/scripts-remapped/build_4mpzm2wl8gipqoxzlms7n6ctq/7gdodk7z6t5iivcgfvflmhqsm/cp_projdf5583fde4f7f1f2f3f5ea117e2cdff1/cache.properties (Too many open files)\n\n```\nYou can see this limit by issuing:\n```\n$ ulimit -a\nopen files                      (-n) 256\n```\n\nIn order to increase the limit, open a new terminal session and issue the command (and verify):\n```\n$ ulimit -n 10000\n\n$ ulimit -a\nopen files                      (-n) 10000\n```\n\n### Gradle Task fails on  `:core:java8:tagImage`\n\nDocker daemon is not started and the Task is not able to push the image to your local registry.\n\n# License\n[Apache 2.0](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fopenwhisk-runtime-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapache%2Fopenwhisk-runtime-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fopenwhisk-runtime-java/lists"}