This is an automated email from the ASF dual-hosted git repository. pdesai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-devtools.git
The following commit(s) were added to refs/heads/master by this push: new 9262859 Seed java runtime source/build files for Knative enablement (#242) 9262859 is described below commit 9262859dcd53333e00fff58ea588b3dee2db2939 Author: Matt Rutkowski <mrutk...@us.ibm.com> AuthorDate: Tue Apr 9 13:25:19 2019 -0500 Seed java runtime source/build files for Knative enablement (#242) * Seed java runtime source/build files for Knative enablement * Seed java runtime source/build files for Knative enablement --- knative-build/runtimes/java/build.gradle | 30 ++++ knative-build/runtimes/java/buildtemplate.yaml | 60 +++++++ .../runtimes/java/core/java8/CHANGELOG.md | 42 +++++ knative-build/runtimes/java/core/java8/Dockerfile | 40 +++++ .../runtimes/java/core/java8/build.gradle | 19 +++ .../runtimes/java/core/java8/delete-build-run.sh | 31 ++++ .../runtimes/java/core/java8/proxy/build.gradle | 45 +++++ .../java/core/java8/proxy/compileClassCache.sh | 22 +++ .../java8/proxy/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes .../proxy/gradle/wrapper/gradle-wrapper.properties | 8 + .../runtimes/java/core/java8/proxy/gradlew | 172 +++++++++++++++++++ .../runtimes/java/core/java8/proxy/gradlew.bat | 84 +++++++++ .../openwhisk/runtime/java/action/JarLoader.java | 94 +++++++++++ .../openwhisk/runtime/java/action/Proxy.java | 188 +++++++++++++++++++++ .../runtime/java/action/WhiskSecurityManager.java | 44 +++++ knative-build/runtimes/java/gradle/README.md | 64 +++++++ knative-build/runtimes/java/gradle/docker.gradle | 116 +++++++++++++ .../java/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes .../java/gradle/wrapper/gradle-wrapper.properties | 8 + knative-build/runtimes/java/gradlew | 172 +++++++++++++++++++ knative-build/runtimes/java/gradlew.bat | 84 +++++++++ knative-build/runtimes/java/settings.gradle | 37 ++++ 22 files changed, 1360 insertions(+) diff --git a/knative-build/runtimes/java/build.gradle b/knative-build/runtimes/java/build.gradle new file mode 100644 index 0000000..4ebd4b8 --- /dev/null +++ b/knative-build/runtimes/java/build.gradle @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath "cz.alenkacz:gradle-scalafmt:${gradle.scalafmt.version}" + } +} + +subprojects { + apply plugin: 'scalafmt' + scalafmt.configFilePath = gradle.scalafmt.config +} diff --git a/knative-build/runtimes/java/buildtemplate.yaml b/knative-build/runtimes/java/buildtemplate.yaml new file mode 100644 index 0000000..d083310 --- /dev/null +++ b/knative-build/runtimes/java/buildtemplate.yaml @@ -0,0 +1,60 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements; and to You under the Apache License, Version 2.0. +apiVersion: build.knative.dev/v1alpha1 +kind: BuildTemplate +metadata: + name: openwhisk-nodejs-runtime +spec: + parameters: + - name: TARGET_IMAGE_NAME + description: name of the image to be tagged and pushed + - name: TARGET_IMAGE_TAG + description: tag the image before pushing + default: "latest" + - name: DOCKERFILE + description: name of the dockerfile + - name: OW_RUNTIME_DEBUG + description: flag to indicate debug mode should be on/off + default: "false" + - name: OW_RUNTIME_PLATFORM + description: flag to indicate the platform, one of ["openwhisk", "knative", ... ] + default: "knative" + - name: OW_ACTION_NAME + description: name of the action + default: "" + - name: OW_ACTION_CODE + description: Java source code to be evaluated + default: "" + - name: OW_ACTION_MAIN + description: name of the function in the "__OW_ACTION_CODE" to call as the action handler + default: "main" + - name: OW_ACTION_BINARY + description: flag to indicate zip function, for zip actions, "__OW_ACTION_CODE" must be base64 encoded string + default: "false" + - name: OW_HTTP_METHODS + description: list of HTTP methods, any combination of [GET, POST, PUT, and DELETE], default is [POST] + default: "[POST]" + - name: OW_ACTION_RAW + description: flag to indicate raw HTTP handling, interpret and process an incoming HTTP body directly + default: "false" + steps: + - name: add-ow-env-to-dockerfile + image: "gcr.io/kaniko-project/executor:debug" + command: + - /busybox/sh + args: + - -c + - | + cat <<EOF >> ${DOCKERFILE} + ENV __OW_RUNTIME_DEBUG "${OW_RUNTIME_DEBUG}" + ENV __OW_RUNTIME_PLATFORM "${OW_RUNTIME_PLATFORM}" + ENV __OW_ACTION_NAME "${OW_ACTION_NAME}" + ENV __OW_ACTION_CODE "${OW_ACTION_CODE}" + ENV __OW_ACTION_MAIN "${OW_ACTION_MAIN}" + ENV __OW_ACTION_BINARY "${OW_ACTION_BINARY}" + ENV __OW_HTTP_METHODS "${OW_HTTP_METHODS}" + ENV __OW_ACTION_RAW "${OW_ACTION_RAW}" + EOF + - name: build-openwhisk-java-runtime + image: "gcr.io/kaniko-project/executor:latest" + args: ["--destination=${TARGET_IMAGE_NAME}:${TARGET_IMAGE_TAG}", "--dockerfile=${DOCKERFILE}"] diff --git a/knative-build/runtimes/java/core/java8/CHANGELOG.md b/knative-build/runtimes/java/core/java8/CHANGELOG.md new file mode 100644 index 0000000..5dfb31b --- /dev/null +++ b/knative-build/runtimes/java/core/java8/CHANGELOG.md @@ -0,0 +1,42 @@ +<!-- +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--> + +# Java 8 OpenWhisk Runtime Container + + +## 1.1.2 +Changes: +- Update run handler to accept more environment variables [#67](https://github.com/apache/incubator-openwhisk-runtime-java/pull/67) + +## 1.1.1 +Changes: +- Adds log markers. +- Improve error handling for improper initialization. + +## 1.1.0 +Changes: +- Replaced oracle [jdk8u131-b11](http://download.oracle.com/otn-pub/java/jdk/"${VERSION}"u"${UPDATE}"-b"${BUILD}"/d54c1d3a095b4ff2b6607d096fa80163/server-jre-"${VERSION}"u"${UPDATE}"-linux-x64.tar.gz) with OpenJDK [adoptopenjdk/openjdk8-openj9:jdk8u162-b12_openj9-0.8.0](https://hub.docker.com/r/adoptopenjdk/openjdk8-openj9) + +## 1.0.1 +Changes: +- Allow custom name for main Class + +## 1.0.0 +Changes: +- Initial release diff --git a/knative-build/runtimes/java/core/java8/Dockerfile b/knative-build/runtimes/java/core/java8/Dockerfile new file mode 100644 index 0000000..3426869 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/Dockerfile @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM adoptopenjdk/openjdk8-openj9:x86_64-ubuntu-jdk8u181-b13_openj9-0.9.0 + +RUN rm -rf /var/lib/apt/lists/* && apt-get clean && apt-get update \ + && apt-get install -y --no-install-recommends locales \ + && rm -rf /var/lib/apt/lists/* \ + && locale-gen en_US.UTF-8 + +ENV LANG="en_US.UTF-8" \ + LANGUAGE="en_US:en" \ + LC_ALL="en_US.UTF-8" \ + VERSION=8 \ + UPDATE=162 \ + BUILD=12 + +ADD proxy /javaAction + +RUN cd /javaAction \ + && rm -rf .classpath .gitignore .gradle .project .settings Dockerfile build \ + && ./gradlew oneJar \ + && rm -rf /javaAction/src \ + && ./compileClassCache.sh + +CMD ["java", "-Dfile.encoding=UTF-8", "-Xshareclasses:cacheDir=/javaSharedCache,readonly", "-Xquickstart", "-jar", "/javaAction/build/libs/javaAction-all.jar"] diff --git a/knative-build/runtimes/java/core/java8/build.gradle b/knative-build/runtimes/java/core/java8/build.gradle new file mode 100644 index 0000000..539efcf --- /dev/null +++ b/knative-build/runtimes/java/core/java8/build.gradle @@ -0,0 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +ext.dockerImageName = 'java8action' +apply from: '../../gradle/docker.gradle' diff --git a/knative-build/runtimes/java/core/java8/delete-build-run.sh b/knative-build/runtimes/java/core/java8/delete-build-run.sh new file mode 100755 index 0000000..8765a31 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/delete-build-run.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Useful for local testing. +# USE WITH CAUTION !! + +# Removes all previously built instances. +docker rm $(docker ps -a -q) + +docker build -t javabox . + +echo "" +echo " ---- RUNNING ---- " +echo "" + +docker run -i -t -p 8080:8080 javabox diff --git a/knative-build/runtimes/java/core/java8/proxy/build.gradle b/knative-build/runtimes/java/core/java8/proxy/build.gradle new file mode 100644 index 0000000..eb28a7c --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/build.gradle @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + compile 'com.google.code.gson:gson:2.6.2' +} + +jar { + manifest { + attributes('Main-Class': 'org.apache.openwhisk.runtime.java.action.Proxy') + } +} + +task oneJar(type: Jar) { + manifest.from jar.manifest + classifier = 'all' + from { + configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } + } { + exclude "META-INF/*.SF" + exclude "META-INF/*.DSA" + exclude "META-INF/*.RSA" + } + with jar +} diff --git a/knative-build/runtimes/java/core/java8/proxy/compileClassCache.sh b/knative-build/runtimes/java/core/java8/proxy/compileClassCache.sh new file mode 100755 index 0000000..79272c6 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/compileClassCache.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#### Construct Class Cache with HTTP Server classes by starting the server #### +java "-Xshareclasses:cacheDir=/javaSharedCache/" "-Xquickstart" "-jar" "/javaAction/build/libs/javaAction-all.jar" & +HTTP_PID=$! +sleep 2 +kill $HTTP_PID diff --git a/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.jar b/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.jar differ diff --git a/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.properties b/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..15c07a0 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,8 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements; and to You under the Apache License, Version 2.0. + +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/knative-build/runtimes/java/core/java8/proxy/gradlew b/knative-build/runtimes/java/core/java8/proxy/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/knative-build/runtimes/java/core/java8/proxy/gradlew.bat b/knative-build/runtimes/java/core/java8/proxy/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/JarLoader.java b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/JarLoader.java new file mode 100644 index 0000000..03f7c90 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/JarLoader.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.openwhisk.runtime.java.action; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Base64; +import java.util.Collections; +import java.util.Map; + +import com.google.gson.JsonObject; + +public class JarLoader extends URLClassLoader { + private final Class<?> mainClass; + private final Method mainMethod; + + public static Path saveBase64EncodedFile(InputStream encoded) throws Exception { + Base64.Decoder decoder = Base64.getDecoder(); + + InputStream decoded = decoder.wrap(encoded); + + File destinationFile = File.createTempFile("useraction", ".jar"); + destinationFile.deleteOnExit(); + Path destinationPath = destinationFile.toPath(); + + Files.copy(decoded, destinationPath, StandardCopyOption.REPLACE_EXISTING); + + return destinationPath; + } + + public JarLoader(Path jarPath, String entrypoint) + throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, SecurityException { + super(new URL[] { jarPath.toUri().toURL() }); + + final String[] splittedEntrypoint = entrypoint.split("#"); + final String entrypointClassName = splittedEntrypoint[0]; + final String entrypointMethodName = splittedEntrypoint.length > 1 ? splittedEntrypoint[1] : "main"; + + this.mainClass = loadClass(entrypointClassName); + + Method m = mainClass.getMethod(entrypointMethodName, new Class[] { JsonObject.class }); + m.setAccessible(true); + int modifiers = m.getModifiers(); + if (m.getReturnType() != JsonObject.class || !Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { + throw new NoSuchMethodException("main"); + } + + this.mainMethod = m; + } + + public JsonObject invokeMain(JsonObject arg, Map<String, String> env) throws Exception { + augmentEnv(env); + return (JsonObject) mainMethod.invoke(null, arg); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static void augmentEnv(Map<String, String> newEnv) { + try { + for (Class cl : Collections.class.getDeclaredClasses()) { + if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) { + Field field = cl.getDeclaredField("m"); + field.setAccessible(true); + Object obj = field.get(System.getenv()); + Map<String, String> map = (Map<String, String>) obj; + map.putAll(newEnv); + } + } + } catch (Exception e) {} + } +} diff --git a/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/Proxy.java b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/Proxy.java new file mode 100644 index 0000000..e9959b9 --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/Proxy.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.openwhisk.runtime.java.action; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class Proxy { + private HttpServer server; + + private JarLoader loader = null; + + public Proxy(int port) throws IOException { + this.server = HttpServer.create(new InetSocketAddress(port), -1); + + this.server.createContext("/init", new InitHandler()); + this.server.createContext("/run", new RunHandler()); + this.server.setExecutor(null); // creates a default executor + } + + public void start() { + server.start(); + } + + private static void writeResponse(HttpExchange t, int code, String content) throws IOException { + byte[] bytes = content.getBytes(StandardCharsets.UTF_8); + t.sendResponseHeaders(code, bytes.length); + OutputStream os = t.getResponseBody(); + os.write(bytes); + os.close(); + } + + private static void writeError(HttpExchange t, String errorMessage) throws IOException { + JsonObject message = new JsonObject(); + message.addProperty("error", errorMessage); + writeResponse(t, 502, message.toString()); + } + + private static void writeLogMarkers() { + System.out.println("XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX"); + System.err.println("XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX"); + System.out.flush(); + System.err.flush(); + } + + private class InitHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + if (loader != null) { + String errorMessage = "Cannot initialize the action more than once."; + System.err.println(errorMessage); + Proxy.writeError(t, errorMessage); + return; + } + + try { + InputStream is = t.getRequestBody(); + JsonParser parser = new JsonParser(); + JsonElement ie = parser.parse(new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))); + JsonObject inputObject = ie.getAsJsonObject(); + + if (inputObject.has("value")) { + JsonObject message = inputObject.getAsJsonObject("value"); + if (message.has("main") && message.has("code")) { + String mainClass = message.getAsJsonPrimitive("main").getAsString(); + String base64Jar = message.getAsJsonPrimitive("code").getAsString(); + + // FIXME: this is obviously not very useful. The idea is that we + // will implement/use a streaming parser for the incoming JSON object so that we + // can stream the contents of the jar straight to a file. + InputStream jarIs = new ByteArrayInputStream(base64Jar.getBytes(StandardCharsets.UTF_8)); + + // Save the bytes to a file. + Path jarPath = JarLoader.saveBase64EncodedFile(jarIs); + + // Start up the custom classloader. This also checks that the + // main method exists. + loader = new JarLoader(jarPath, mainClass); + + Proxy.writeResponse(t, 200, "OK"); + return; + } + } + + Proxy.writeError(t, "Missing main/no code to execute."); + return; + } catch (Exception e) { + e.printStackTrace(System.err); + writeLogMarkers(); + Proxy.writeError(t, "An error has occurred (see logs for details): " + e); + return; + } + } + } + + private class RunHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + if (loader == null) { + Proxy.writeError(t, "Cannot invoke an uninitialized action."); + return; + } + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + SecurityManager sm = System.getSecurityManager(); + + try { + InputStream is = t.getRequestBody(); + JsonParser parser = new JsonParser(); + JsonObject body = parser.parse(new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))).getAsJsonObject(); + JsonObject inputObject = body.getAsJsonObject("value"); + + HashMap<String, String> env = new HashMap<String, String>(); + Set<Map.Entry<String, JsonElement>> entrySet = body.entrySet(); + for(Map.Entry<String, JsonElement> entry : entrySet){ + try { + if(!entry.getKey().equalsIgnoreCase("value")) + env.put(String.format("__OW_%s", entry.getKey().toUpperCase()), entry.getValue().getAsString()); + } catch (Exception e) {} + } + + Thread.currentThread().setContextClassLoader(loader); + System.setSecurityManager(new WhiskSecurityManager()); + + // User code starts running here. + JsonObject output = loader.invokeMain(inputObject, env); + // User code finished running here. + + if (output == null) { + throw new NullPointerException("The action returned null"); + } + + Proxy.writeResponse(t, 200, output.toString()); + return; + } catch (InvocationTargetException ite) { + // These are exceptions from the action, wrapped in ite because + // of reflection + Throwable underlying = ite.getCause(); + underlying.printStackTrace(System.err); + Proxy.writeError(t, + "An error has occured while invoking the action (see logs for details): " + underlying); + } catch (Exception e) { + e.printStackTrace(System.err); + Proxy.writeError(t, "An error has occurred (see logs for details): " + e); + } finally { + writeLogMarkers(); + System.setSecurityManager(sm); + Thread.currentThread().setContextClassLoader(cl); + } + } + } + + public static void main(String args[]) throws Exception { + Proxy proxy = new Proxy(8080); + proxy.start(); + } +} diff --git a/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/WhiskSecurityManager.java b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/WhiskSecurityManager.java new file mode 100644 index 0000000..f9b93ea --- /dev/null +++ b/knative-build/runtimes/java/core/java8/proxy/src/main/java/org/apache/openwhisk/runtime/java/action/WhiskSecurityManager.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.openwhisk.runtime.java.action; + +import java.security.Permission; + +/** + * A `SecurityManager` installed when executing action code. The purpose here + * is not so much to prevent malicious behavior than it is to prevent users from + * shooting themselves in the foot. In particular, anything that kills the JVM + * will result in unhelpful action error messages. + */ +public class WhiskSecurityManager extends SecurityManager { + @Override + public void checkPermission(Permission p) { + // Not throwing means accepting anything. + } + + @Override + public void checkPermission(Permission p, Object ctx) { + // Not throwing means accepting anything. + } + + @Override + public void checkExit(int status) { + super.checkExit(status); + throw new SecurityException("System.exit(" + status + ") called from within an action."); + } +} diff --git a/knative-build/runtimes/java/gradle/README.md b/knative-build/runtimes/java/gradle/README.md new file mode 100644 index 0000000..14842f1 --- /dev/null +++ b/knative-build/runtimes/java/gradle/README.md @@ -0,0 +1,64 @@ +<!-- +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--> + +# Gradle + +Gradle is used to build OpenWhisk. It does not need to be pre-installed as it installs itself using the [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html). To use it without installing, simply invoke the `gradlew` command at the root of the repository. You can also install `gradle` via [`apt`](http://linuxg.net/how-to-install-gradle-2-1-on-ubuntu-14-10-ubuntu-14-04-ubuntu-12-04-and-derivatives/) on Ubuntu or [`brew`](http://www.brewformulas.org/Gradle) on Mac [...] + +## Usage + +In general, project level properties are set via `-P{propertyName}={propertyValue}`. A task is called via `gradle {taskName}` and a subproject task is called via `gradle :path:to:subproject:{taskName}`. To run tasks in parallel, use the `--parallel` flag (**Note:** It's an incubating feature and might break stuff). + +### Build + +To build all Docker images use `gradle distDocker` at the top level project, to build a specific component use `gradle :core:controller:distDocker`. + +Project level options that can be used on `distDocker`: + +- `dockerImageName` (*required*): The name of the image to build (e.g. whisk/controller) +- `dockerHost` (*optional*): The docker host to run commands on, default behaviour is docker's own `DOCKER_HOST` environment variable +- `dockerRegistry` (*optional*): The registry to push to +- `dockerImageTag` (*optional*, default 'latest'): The tag for the image +- `dockerTimeout` (*optional*, default 240): Timeout for docker operations in seconds +- `dockerRetries` (*optional*, default 3): How many times to retry docker operations +- `dockerBinary` (*optional*, default `docker`): The binary to execute docker commands + +### Test + +To run tests one uses the `test` task. OpenWhisk consolidates tests into a single `tests` project. Hence the command to run all tests is `gradle :tests:test`. + +It is possible to run specific tests using [Gradle testfilters](https://docs.gradle.org/current/userguide/java_plugin.html#test_filtering). For example `gradle :tests:test --tests "your.package.name.TestClass.evenMethodName"`. Wildcard `*` may be used anywhere. + +## Build your own `build.gradle` +In Gradle, most of the tasks we use are default tasks provided by plugins in Gradle. The [`scala` Plugin](https://docs.gradle.org/current/userguide/scala_plugin.html) for example includes tasks, that are needed to build Scala projects. Moreover, Gradle is aware of *Applications*. The [`application` Plugin](https://docs.gradle.org/current/userguide/application_plugin.html) provides tasks that are required to distribute a self-contained application. When `application` and `scala` are used [...] + +In OpenWhisk, we want to distribute our application via Docker images. Hence we wrote a "plugin" that creates the task `distDocker`. That task will build an image from the `Dockerfile` that is located next to the `build.gradle` it is called from, for example Controller's `Dockerfile` and `build.gradle` are both located at `core/controller`. + +If you want to create a new `build.gradle` for your component, simply put the `Dockerfile` right next to it and include `docker.gradle` by using + +``` +ext.dockerImageName = 'openwwhisk/{IMAGENAME}' +apply from: 'path/to/docker.gradle' +``` + +If your component needs to be build before you can build the image, make `distDocker` depend on any task needed to run before it, for example: + +``` +distDocker.dependsOn ':common:scala:distDocker', 'distTar' +``` diff --git a/knative-build/runtimes/java/gradle/docker.gradle b/knative-build/runtimes/java/gradle/docker.gradle new file mode 100644 index 0000000..6ad6850 --- /dev/null +++ b/knative-build/runtimes/java/gradle/docker.gradle @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import groovy.time.* + +/** + * Utility to build docker images based in gradle projects + * + * This extends gradle's 'application' plugin logic with a 'distDocker' task which builds + * a docker image from the Dockerfile of the project that applies this file. The image + * is automatically tagged and pushed if a tag and/or a registry is given. + * + * Parameters that can be set on project level: + * - dockerImageName (required): The name of the image to build (e.g. controller) + * - dockerRegistry (optional): The registry to push to + * - dockerImageTag (optional, default 'latest'): The tag for the image + * - dockerImagePrefix (optional, default 'whisk'): The prefix for the image, + * 'controller' becomes 'whisk/controller' per default + * - dockerTimeout (optional, default 840): Timeout for docker operations in seconds + * - dockerRetries (optional, default 3): How many times to retry docker operations + * - dockerBinary (optional, default 'docker'): The binary to execute docker commands + * - dockerBuildArgs (options, default ''): Project specific custom docker build arguments + * - dockerHost (optional): The docker host to run commands on, default behaviour is + * docker's own DOCKER_HOST environment variable + */ + +ext { + dockerRegistry = project.hasProperty('dockerRegistry') ? dockerRegistry + '/' : '' + dockerImageTag = project.hasProperty('dockerImageTag') ? dockerImageTag : 'latest' + dockerImagePrefix = project.hasProperty('dockerImagePrefix') ? dockerImagePrefix : 'whisk' + dockerTimeout = project.hasProperty('dockerTimeout') ? dockerTimeout.toInteger() : 840 + dockerRetries = project.hasProperty('dockerRetries') ? dockerRetries.toInteger() : 3 + dockerBinary = project.hasProperty('dockerBinary') ? [dockerBinary] : ['docker'] + dockerBuildArg = ['build'] +} +ext.dockerTaggedImageName = dockerRegistry + dockerImagePrefix + '/' + dockerImageName + ':' + dockerImageTag + +if(project.hasProperty('dockerHost')) { + dockerBinary += ['--host', project.dockerHost] +} + +if(project.hasProperty('dockerBuildArgs')) { + dockerBuildArgs.each { arg -> + dockerBuildArg += ['--build-arg', arg] + } +} + +task distDocker { + doLast { + def start = new Date() + def cmd = dockerBinary + dockerBuildArg + ['-t', dockerImageName, project.buildscript.sourceFile.getParentFile().getAbsolutePath()] + retry(cmd, dockerRetries, dockerTimeout) + println("Building '${dockerImageName}' took ${TimeCategory.minus(new Date(), start)}") + } +} +task tagImage { + doLast { + def versionString = (dockerBinary + ['-v']).execute().text + def matched = (versionString =~ /(\d+)\.(\d+)\.(\d+)/) + + def major = matched[0][1] as int + def minor = matched[0][2] as int + + def dockerCmd = ['tag'] + if(major == 1 && minor < 12) { + dockerCmd += ['-f'] + } + retry(dockerBinary + dockerCmd + [dockerImageName, dockerTaggedImageName], dockerRetries, dockerTimeout) + } +} + +task pushImage { + doLast { + def cmd = dockerBinary + ['push', dockerTaggedImageName] + retry(cmd, dockerRetries, dockerTimeout) + } +} +pushImage.dependsOn tagImage +pushImage.onlyIf { dockerRegistry != '' } +distDocker.finalizedBy pushImage + +def retry(cmd, retries, timeout) { + println("${new Date()}: Executing '${cmd.join(" ")}'") + def proc = cmd.execute() + proc.consumeProcessOutput(System.out, System.err) + proc.waitForOrKill(timeout * 1000) + if(proc.exitValue() != 0) { + def message = "${new Date()}: Command '${cmd.join(" ")}' failed with exitCode ${proc.exitValue()}" + if(proc.exitValue() == 143) { // 143 means the process was killed (SIGTERM signal) + message = "${new Date()}: Command '${cmd.join(" ")}' was killed after ${timeout} seconds" + } + + if(retries > 1) { + println("${message}, ${retries-1} retries left, retrying...") + retry(cmd, retries-1, timeout) + } + else { + println("${message}, no more retries left, aborting...") + throw new GradleException(message) + } + } +} diff --git a/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.jar b/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.jar differ diff --git a/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.properties b/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..15c07a0 --- /dev/null +++ b/knative-build/runtimes/java/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,8 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements; and to You under the Apache License, Version 2.0. + +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/knative-build/runtimes/java/gradlew b/knative-build/runtimes/java/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/knative-build/runtimes/java/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/knative-build/runtimes/java/gradlew.bat b/knative-build/runtimes/java/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/knative-build/runtimes/java/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/knative-build/runtimes/java/settings.gradle b/knative-build/runtimes/java/settings.gradle new file mode 100644 index 0000000..464ae37 --- /dev/null +++ b/knative-build/runtimes/java/settings.gradle @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +include 'tests' + +include 'core:java8' +include 'core:java8:proxy' + +rootProject.name = 'runtime-java' + +gradle.ext.openwhisk = [ + version: '1.0.0-SNAPSHOT' +] + +gradle.ext.scala = [ + version: '2.12.7', + compileFlags: ['-feature', '-unchecked', '-deprecation', '-Xfatal-warnings', '-Ywarn-unused-import'] +] + +gradle.ext.scalafmt = [ + version: '1.5.0', + config: new File(rootProject.projectDir, '.scalafmt.conf') +]