Refactor tests, update changelog (#39) * Refactor java8 directories and update changelog * refactor tests * update .gitaatributes * remove extra lines * remove statement about default base on extension * update changelog
diff --git a/.gitattributes b/.gitattributes index b19d1c0..eb77ecc 100644 --- a/.gitattributes +++ b/.gitattributes
@@ -26,6 +26,6 @@ # bash files not having the .sh extension tools/vagrant/simple/wsk text eol=lf gradlew text eol=lf -core/javaAction/proxy/gradlew text eol=lf +java8/proxy/gradlew text eol=lf tools/vagrant/hello text eol=lf sdk/docker/client/action text eol=lf
diff --git a/.travis.yml b/.travis.yml index 1e65e8b..9886719 100644 --- a/.travis.yml +++ b/.travis.yml
@@ -18,7 +18,7 @@ group: deprecated-2017Q3 language: scala scala: -- 2.11.8 +- 2.11.11 services: - docker
diff --git a/README.md b/README.md index 1c92f9d..5052591 100644 --- a/README.md +++ b/README.md
@@ -1,16 +1,16 @@ <!-- # -# Licensed to the Apache Software Foundation (ASF) under one or more contributor -# license agreements. See the NOTICE file distributed with this work for additional +# 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 +# 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 +# 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. # @@ -20,30 +20,88 @@ [](https://travis-ci.org/apache/incubator-openwhisk-runtime-java) +## Changelogs +- [Java 8 CHANGELOG.md](java8/CHANGELOG.md) -### Give it a try today -To use as a docker action + +## Quick Java Action +A Java action is a Java program with a method called `main` that has the exact signature as follows: +```java +public static com.google.gson.JsonObject main(com.google.gson.JsonObject); ``` -wsk action update myAction myAction.jar --docker openwhisk/java8action:1.0.0 + +For example, create a Java file called `Hello.java` with the following content: + +```java +import com.google.gson.JsonObject; + +public class Hello { + public static JsonObject main(JsonObject args) { + String name = "stranger"; + if (args.has("name")) + name = args.getAsJsonPrimitive("name").getAsString(); + JsonObject response = new JsonObject(); + response.addProperty("greeting", "Hello " + name + "!"); + return response; + } +} +``` +In order to compile, test and archive Java files, you must have a [JDK 8](http://openjdk.java.net/install/) installed locally. + +Then, compile `Hello.java` into a JAR file `hello.jar` as follows: +``` +javac Hello.java +``` +``` +jar cvf hello.jar Hello.class +``` + +**Note:** [google-gson](https://github.com/google/gson) must exist in your Java CLASSPATH when compiling the Java file. + +You need to specify the name of the main class using `--main`. An eligible main +class is one that implements a static `main` method as described above. If the +class is not in the default package, use the Java fully-qualified class name, +e.g., `--main com.example.MyMain`. + +If needed you can also customize the method name of your Java action. This +can be done by specifying the Java fully-qualified method name of your action, +e.q., `--main com.example.MyMain#methodName` + +### Create the Java Action +To use as a docker action: +``` +wsk action update helloJava hello.jar --main Hello --docker openwhisk/java8action ``` This works on any deployment of Apache OpenWhisk -### To use on deployment that contains the rutime as a kind -To use as a kind action +To use on a deployment of OpenWhisk that contains the runtime as a kind: ``` -wsk action update myAction myAction.jar --kind java:8 +wsk action update helloJava hello.jar --main Hello --kind java:8 ``` -### Local development +### Invoke the Java Action +Action invocation is the same for Java actions as it is for Swift and JavaScript actions: + ``` -./gradlew core:javaAction:distDocker +wsk action invoke --result helloJava --param name World +``` + +```json + { + "greeting": "Hello World!" + } +``` + +## Local development +``` +./gradlew java8:distDocker ``` This will produce the image `whisk/java8action` Build and Push image ``` docker login -./gradlew core:javaAction:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io +./gradlew java8:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io ``` Deploy OpenWhisk using ansible environment that contains the kind `java:8` @@ -71,16 +129,11 @@ ### Testing Install dependencies from the root directory on $OPENWHISK_HOME repository ``` -./gradlew :common:scala:install :core:controller:install :core:invoker:install :tests:install +pushd $OPENWHISK_HOME +./gradlew install +podd $OPENWHISK_HOME ``` -Using gradle for the ActionContainer tests you need to use a proxy if running on Mac, if Linux then don't use proxy options -You can pass the flags `-Dhttp.proxyHost=localhost -Dhttp.proxyPort=3128` directly in gradle command. -Or save in your `$HOME/.gradle/gradle.properties` -``` -systemProp.http.proxyHost=localhost -systemProp.http.proxyPort=3128 -``` Using gradle to run all tests ``` ./gradlew :tests:test @@ -92,11 +145,6 @@ Using IntelliJ: - Import project as gradle project. - Make sure working directory is root of the project/repo -- Add the following Java VM properties in ScalaTests Run Configuration, easiest is to change the Defaults for all ScalaTests to use this VM properties -``` --Dhttp.proxyHost=localhost --Dhttp.proxyPort=3128 -``` #### Using container image to test To use as docker action push to your own dockerhub account @@ -106,7 +154,7 @@ ``` Then create the action using your the image from dockerhub ``` -wsk action update myAction myAction.jar --docker $user_prefix/java8action +wsk action update helloJava hello.jar --main Hello --docker $user_prefix/java8action ``` The `$user_prefix` is usually your dockerhub user id.
diff --git a/core/javaAction/build.gradle b/core/javaAction/build.gradle deleted file mode 100644 index 8688fd7..0000000 --- a/core/javaAction/build.gradle +++ /dev/null
@@ -1,2 +0,0 @@ -ext.dockerImageName = 'java8action' -apply from: '../../gradle/docker.gradle'
diff --git a/CHANGELOG.md b/java8/CHANGELOG.md similarity index 72% rename from CHANGELOG.md rename to java8/CHANGELOG.md index 83d7ed9..efa910f 100644 --- a/CHANGELOG.md +++ b/java8/CHANGELOG.md
@@ -19,6 +19,10 @@ # Java 8 OpenWhisk Runtime Container +## 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
diff --git a/core/javaAction/Dockerfile b/java8/Dockerfile similarity index 100% rename from core/javaAction/Dockerfile rename to java8/Dockerfile
diff --git a/java8/build.gradle b/java8/build.gradle new file mode 100644 index 0000000..57276bc --- /dev/null +++ b/java8/build.gradle
@@ -0,0 +1,2 @@ +ext.dockerImageName = 'java8action' +apply from: '../gradle/docker.gradle'
diff --git a/core/javaAction/delete-build-run.sh b/java8/delete-build-run.sh similarity index 100% rename from core/javaAction/delete-build-run.sh rename to java8/delete-build-run.sh
diff --git a/core/javaAction/proxy/build.gradle b/java8/proxy/build.gradle similarity index 100% rename from core/javaAction/proxy/build.gradle rename to java8/proxy/build.gradle
diff --git a/core/javaAction/proxy/compileClassCache.sh b/java8/proxy/compileClassCache.sh similarity index 100% rename from core/javaAction/proxy/compileClassCache.sh rename to java8/proxy/compileClassCache.sh
diff --git a/core/javaAction/proxy/gradle/wrapper/gradle-wrapper.jar b/java8/proxy/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from core/javaAction/proxy/gradle/wrapper/gradle-wrapper.jar rename to java8/proxy/gradle/wrapper/gradle-wrapper.jar Binary files differ
diff --git a/core/javaAction/proxy/gradle/wrapper/gradle-wrapper.properties b/java8/proxy/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from core/javaAction/proxy/gradle/wrapper/gradle-wrapper.properties rename to java8/proxy/gradle/wrapper/gradle-wrapper.properties
diff --git a/core/javaAction/proxy/gradlew b/java8/proxy/gradlew similarity index 100% rename from core/javaAction/proxy/gradlew rename to java8/proxy/gradlew
diff --git a/core/javaAction/proxy/gradlew.bat b/java8/proxy/gradlew.bat similarity index 100% rename from core/javaAction/proxy/gradlew.bat rename to java8/proxy/gradlew.bat
diff --git a/core/javaAction/proxy/src/main/java/openwhisk/java/action/JarLoader.java b/java8/proxy/src/main/java/openwhisk/java/action/JarLoader.java similarity index 100% rename from core/javaAction/proxy/src/main/java/openwhisk/java/action/JarLoader.java rename to java8/proxy/src/main/java/openwhisk/java/action/JarLoader.java
diff --git a/core/javaAction/proxy/src/main/java/openwhisk/java/action/Proxy.java b/java8/proxy/src/main/java/openwhisk/java/action/Proxy.java similarity index 100% rename from core/javaAction/proxy/src/main/java/openwhisk/java/action/Proxy.java rename to java8/proxy/src/main/java/openwhisk/java/action/Proxy.java
diff --git a/core/javaAction/proxy/src/main/java/openwhisk/java/action/WhiskSecurityManager.java b/java8/proxy/src/main/java/openwhisk/java/action/WhiskSecurityManager.java similarity index 100% rename from core/javaAction/proxy/src/main/java/openwhisk/java/action/WhiskSecurityManager.java rename to java8/proxy/src/main/java/openwhisk/java/action/WhiskSecurityManager.java
diff --git a/settings.gradle b/settings.gradle index 45864ea..f7cf2f9 100644 --- a/settings.gradle +++ b/settings.gradle
@@ -1,7 +1,8 @@ include 'tests' -include 'core:javaAction' -include 'core:javaAction:proxy' +include 'java8' +include 'java8:proxy' + rootProject.name = 'runtime-java' @@ -10,7 +11,7 @@ ] gradle.ext.scala = [ - version: '2.11.8', + version: '2.11.11', compileFlags: ['-feature', '-unchecked', '-deprecation', '-Xfatal-warnings', '-Ywarn-unused-import'] ]
diff --git a/tests/src/test/scala/actionContainers/ActionContainer.scala b/tests/src/test/scala/actionContainers/ActionContainer.scala deleted file mode 100644 index 56aa131..0000000 --- a/tests/src/test/scala/actionContainers/ActionContainer.scala +++ /dev/null
@@ -1,174 +0,0 @@ -/* - * 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 runtime.actionContainers - -import java.io.ByteArrayOutputStream -import java.io.File -import java.io.PrintWriter - -import scala.concurrent.Await -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future -import scala.concurrent.blocking -import scala.concurrent.duration.Duration -import scala.concurrent.duration.DurationInt -import scala.language.postfixOps -import scala.sys.process.ProcessLogger -import scala.sys.process.stringToProcess -import scala.util.Random - -import org.apache.commons.lang3.StringUtils -import org.scalatest.FlatSpec -import org.scalatest.Matchers - -import akka.actor.ActorSystem -import common.WhiskProperties -import spray.json._ -import whisk.core.entity.Exec - -/** - * For testing convenience, this interface abstracts away the REST calls to a - * container as blocking method calls of this interface. - */ -trait ActionContainer { - def init(value: JsValue): (Int, Option[JsObject]) - def run(value: JsValue): (Int, Option[JsObject]) -} - -trait ActionProxyContainerTestUtils extends FlatSpec with Matchers { - import ActionContainer.{filterSentinel, sentinel} - - def initPayload(code: String, main: String = "main") = { - JsObject( - "value" -> JsObject( - "code" -> { if (code != null) JsString(code) else JsNull }, - "main" -> JsString(main), - "binary" -> JsBoolean(Exec.isBinaryCode(code)))) - } - - def runPayload(args: JsValue, other: Option[JsObject] = None) = { - JsObject(Map("value" -> args) ++ (other map { _.fields } getOrElse Map())) - } - - def checkStreams(out: String, err: String, additionalCheck: (String, String) => Unit, sentinelCount: Int = 1) = { - withClue("expected number of stdout sentinels") { - sentinelCount shouldBe StringUtils.countMatches(out, sentinel) - } - withClue("expected number of stderr sentinels") { - sentinelCount shouldBe StringUtils.countMatches(err, sentinel) - } - - val (o, e) = (filterSentinel(out), filterSentinel(err)) - o should not include (sentinel) - e should not include (sentinel) - additionalCheck(o, e) - } -} - -object ActionContainer { - private lazy val dockerBin: String = { - List("/usr/bin/docker", "/usr/local/bin/docker") - .find { bin => - new File(bin).isFile() - } - .getOrElse(???) // This fails if the docker binary couldn't be located. - } - - private lazy val dockerCmd: String = { - val version = WhiskProperties.getProperty("whisk.version.name") - // Check if we are running on docker-machine env. - val hostStr = if (version.toLowerCase().contains("mac")) { - s" --host tcp://${WhiskProperties.getMainDockerEndpoint()} " - } else { - " " - } - s"$dockerBin $hostStr" - } - - private def docker(command: String): String = s"$dockerCmd $command" - - // Runs a process asynchronously. Returns a future with (exitCode,stdout,stderr) - private def proc(cmd: String): Future[(Int, String, String)] = Future { - blocking { - val out = new ByteArrayOutputStream - val err = new ByteArrayOutputStream - val outW = new PrintWriter(out) - val errW = new PrintWriter(err) - val v = cmd ! (ProcessLogger(outW.println, errW.println)) - outW.close() - errW.close() - (v, out.toString, err.toString) - } - } - - // Tying it all together, we have a method that runs docker, waits for - // completion for some time then returns the exit code, the output stream - // and the error stream. - private def awaitDocker(cmd: String, t: Duration): (Int, String, String) = { - Await.result(proc(docker(cmd)), t) - } - - // Filters out the sentinel markers inserted by the container (see relevant private code in Invoker.scala) - val sentinel = "XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX" - def filterSentinel(str: String) = str.replaceAll(sentinel, "").trim - - def withContainer(imageName: String, environment: Map[String, String] = Map.empty)(code: ActionContainer => Unit)( - implicit actorSystem: ActorSystem): (String, String) = { - val rand = { val r = Random.nextInt; if (r < 0) -r else r } - val name = imageName.toLowerCase.replaceAll("""[^a-z]""", "") + rand - val envArgs = environment.toSeq.map { - case (k, v) => s"-e ${k}=${v}" - } mkString (" ") - - // We create the container... - val runOut = awaitDocker(s"run --name $name $envArgs -d $imageName", 10 seconds) - assert(runOut._1 == 0, "'docker run' did not exit with 0: " + runOut) - - // ...find out its IP address... - val ipOut = awaitDocker(s"""inspect --format '{{.NetworkSettings.IPAddress}}' $name""", 10 seconds) - assert(ipOut._1 == 0, "'docker inspect did not exit with 0") - val ip = ipOut._2.replaceAll("""[^0-9.]""", "") - - // ...we create an instance of the mock container interface... - val mock = new ActionContainer { - def init(value: JsValue) = syncPost(ip, 8080, "/init", value) - def run(value: JsValue) = syncPost(ip, 8080, "/run", value) - } - - try { - // ...and finally run the code with it. - code(mock) - // I'm told this is good for the logs. - Thread.sleep(100) - val (_, out, err) = awaitDocker(s"logs $name", 10 seconds) - (out, err) - } finally { - awaitDocker(s"kill $name", 10 seconds) - awaitDocker(s"rm $name", 10 seconds) - } - } - - private def syncPost(host: String, port: Int, endPoint: String, content: JsValue): (Int, Option[JsObject]) = { - whisk.core.containerpool.HttpUtils.post(host, port, endPoint, content) - } - - private class ActionContainerImpl() extends ActionContainer { - override def init(value: JsValue) = ??? - override def run(value: JsValue) = ??? - } -}
diff --git a/tests/src/test/scala/actionContainers/JavaActionContainerTests.scala b/tests/src/test/scala/actionContainers/JavaActionContainerTests.scala index 7992892..f30ccd1 100644 --- a/tests/src/test/scala/actionContainers/JavaActionContainerTests.scala +++ b/tests/src/test/scala/actionContainers/JavaActionContainerTests.scala
@@ -18,16 +18,14 @@ package actionContainers import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner import org.scalatest.FlatSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import common.WskActorSystem import spray.json.DefaultJsonProtocol._ import spray.json._ - -import ActionContainer.withContainer -import ResourceHelpers.JarBuilder - -import common.WskActorSystem +import actionContainers.ResourceHelpers.JarBuilder +import actionContainers.ActionContainer.withContainer @RunWith(classOf[JUnitRunner]) class JavaActionContainerTests extends FlatSpec with Matchers with WskActorSystem with ActionProxyContainerTestUtils {
diff --git a/tests/src/test/scala/actionContainers/ResourceHelpers.scala b/tests/src/test/scala/actionContainers/ResourceHelpers.scala deleted file mode 100644 index 08f46e4..0000000 --- a/tests/src/test/scala/actionContainers/ResourceHelpers.scala +++ /dev/null
@@ -1,190 +0,0 @@ -/* - * 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 runtime.actionContainers - -import java.net.URI -import java.net.URLClassLoader -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.SimpleFileVisitor -import java.nio.file.FileVisitResult -import java.nio.file.FileSystems -import java.nio.file.attribute.BasicFileAttributes -import java.nio.charset.StandardCharsets -import java.util.Base64 - -import javax.tools.ToolProvider - -import collection.JavaConverters._ - -/** - * A collection of utility objects to create ephemeral action resources based - * on file contents. - */ -object ResourceHelpers { - - /** Creates a zip file based on the contents of a top-level directory. */ - object ZipBuilder { - def mkBase64Zip(sources: Seq[(Seq[String], String)]): String = { - val (tmpDir, _) = writeSourcesToTempDirectory(sources) - val archive = makeZipFromDir(tmpDir) - readAsBase64(archive) - } - } - - /** - * A convenience object to compile and package Java sources into a JAR, and to - * encode that JAR as a base 64 string. The compilation options include the - * current classpath, which is why Google GSON is readily available (though not - * packaged in the JAR). - */ - object JarBuilder { - def mkBase64Jar(sources: Seq[(Seq[String], String)]): String = { - // Note that this pipeline doesn't delete any of the temporary files. - val binDir = compile(sources) - val jarPath = makeJarFromDir(binDir) - val base64 = readAsBase64(jarPath) - base64 - } - - def mkBase64Jar(source: (Seq[String], String)): String = { - mkBase64Jar(Seq(source)) - } - - private def compile(sources: Seq[(Seq[String], String)]): Path = { - require(!sources.isEmpty) - - // The absolute paths of the source file - val (srcDir, srcAbsPaths) = writeSourcesToTempDirectory(sources) - - // A temporary directory for the destination files. - val binDir = Files.createTempDirectory("bin").toAbsolutePath() - - // Preparing the compiler - val compiler = ToolProvider.getSystemJavaCompiler() - val fileManager = compiler.getStandardFileManager(null, null, StandardCharsets.UTF_8) - - // Collecting all files to be compiled - val compUnit = fileManager.getJavaFileObjectsFromFiles(srcAbsPaths.map(_.toFile).asJava) - - // Setting the options - val compOptions = Seq("-d", binDir.toAbsolutePath().toString(), "-classpath", buildClassPath()) - val compTask = compiler.getTask(null, fileManager, null, compOptions.asJava, null, compUnit) - - // ...and off we go. - compTask.call() - - binDir - } - - private def buildClassPath(): String = { - val bcp = System.getProperty("java.class.path") - - val list = this.getClass().getClassLoader() match { - case ucl: URLClassLoader => - bcp :: ucl.getURLs().map(_.getFile().toString()).toList - - case _ => - List(bcp) - } - - list.mkString(System.getProperty("path.separator")) - } - } - - /** - * Creates a temporary directory and reproduces the desired file structure - * in it. Returns the path of the temporary directory and the path of each - * file as represented in it. - */ - private def writeSourcesToTempDirectory(sources: Seq[(Seq[String], String)]): (Path, Seq[Path]) = { - // A temporary directory for the source files. - val srcDir = Files.createTempDirectory("src").toAbsolutePath() - - val srcAbsPaths = for ((sourceName, sourceContent) <- sources) yield { - // The relative path of the source file - val srcRelPath = Paths.get(sourceName.head, sourceName.tail: _*) - // The absolute path of the source file - val srcAbsPath = srcDir.resolve(srcRelPath) - // Create parent directories if needed. - Files.createDirectories(srcAbsPath.getParent) - // Writing contents - Files.write(srcAbsPath, sourceContent.getBytes(StandardCharsets.UTF_8)) - - srcAbsPath - } - - (srcDir, srcAbsPaths) - } - - private def makeZipFromDir(dir: Path): Path = makeArchiveFromDir(dir, ".zip") - - private def makeJarFromDir(dir: Path): Path = makeArchiveFromDir(dir, ".jar") - - /** - * Compresses all files beyond a directory into a zip file. - * Note that Jar files are just zip files. - */ - private def makeArchiveFromDir(dir: Path, extension: String): Path = { - // Any temporary file name for the archive. - val arPath = Files.createTempFile("output", extension).toAbsolutePath() - - // We "mount" it as a filesystem, so we can just copy files into it. - val dstUri = new URI("jar:" + arPath.toUri().getScheme(), arPath.toAbsolutePath().toString(), null) - // OK, that's a hack. Doing this because newFileSystem wants to create that file. - arPath.toFile().delete() - val fs = FileSystems.newFileSystem(dstUri, Map(("create" -> "true")).asJava) - - // Traversing all files in the bin directory... - Files.walkFileTree( - dir, - new SimpleFileVisitor[Path]() { - override def visitFile(path: Path, attributes: BasicFileAttributes) = { - // The path relative to the src dir - val relPath = dir.relativize(path) - - // The corresponding path in the zip - val arRelPath = fs.getPath(relPath.toString()) - - // If this file is not top-level in the src dir... - if (relPath.getParent() != null) { - // ...create the directory structure if it doesn't exist. - if (!Files.exists(arRelPath.getParent())) { - Files.createDirectories(arRelPath.getParent()) - } - } - - // Finally we can copy that file. - Files.copy(path, arRelPath) - - FileVisitResult.CONTINUE - } - }) - - fs.close() - - arPath - } - - /** Reads the contents of a (possibly binary) file into a base64-encoded String */ - def readAsBase64(path: Path): String = { - val encoder = Base64.getEncoder() - new String(encoder.encode(Files.readAllBytes(path)), StandardCharsets.UTF_8) - } -}
diff --git a/tools/travis/publish.sh b/tools/travis/publish.sh index 503ddc0..82a6adb 100755 --- a/tools/travis/publish.sh +++ b/tools/travis/publish.sh
@@ -31,9 +31,9 @@ IMAGE_TAG=$3 if [ ${RUNTIME_VERSION} == "8" ]; then - RUNTIME="javaAction" -elif [ ${RUNTIME_VERSION} == "9" ]; then - RUNTIME="java9Action" + RUNTIME="java8" +elif [ ${RUNTIME_VERSION} == "10" ]; then + RUNTIME="java10" fi if [[ ! -z ${DOCKER_USER} ]] && [[ ! -z ${DOCKER_PASSWORD} ]]; then @@ -42,7 +42,7 @@ if [[ ! -z ${RUNTIME} ]]; then TERM=dumb ./gradlew \ -:core:${RUNTIME}:distDocker \ +:${RUNTIME}:distDocker \ -PdockerRegistry=docker.io \ -PdockerImagePrefix=${IMAGE_PREFIX} \ -PdockerImageTag=${IMAGE_TAG}