From 03fb9d4be296c85b25f4113bd86336393a72a1ce Mon Sep 17 00:00:00 2001 From: Konstantinos Chalkias Date: Tue, 24 Apr 2018 18:43:07 +0100 Subject: [PATCH 1/4] CORDA-1354 Check for jars in nested folders (to add in classpath) (#2981) + edge cases (logging if we don't have permission to jar folders) --- node/src/main/java/CordaCaplet.java | 60 ++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/node/src/main/java/CordaCaplet.java b/node/src/main/java/CordaCaplet.java index c9201a3621..af8faa7fc7 100644 --- a/node/src/main/java/CordaCaplet.java +++ b/node/src/main/java/CordaCaplet.java @@ -4,8 +4,6 @@ import com.typesafe.config.*; import sun.misc.Signal; -import sun.misc.SignalHandler; - import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -80,9 +78,11 @@ public class CordaCaplet extends Capsule { if (ATTR_APP_CLASS_PATH == attr) { T cp = super.attribute(attr); - (new File(baseDir, "cordapps")).mkdir(); - // Add additional directories of JARs to the classpath (at the end). e.g. for JDBC drivers - augmentClasspath((List) cp, new File(baseDir, "cordapps")); + File cordappsDir = new File(baseDir, "cordapps"); + // Create cordapps directory if it doesn't exist. + requireCordappsDirExists(cordappsDir); + // Add additional directories of JARs to the classpath (at the end), e.g., for JDBC drivers. + augmentClasspath((List) cp, cordappsDir); try { List jarDirs = nodeConfig.getStringList("jarDirs"); log(LOG_VERBOSE, "Configured JAR directories = " + jarDirs); @@ -128,24 +128,58 @@ public class CordaCaplet extends Capsule { } private void augmentClasspath(List classpath, File dir) { - if (dir.exists()) { - File[] files = dir.listFiles(); - for (File file : files) { + try { + if (dir.exists()) { + // The following might return null if the directory is not there (we check this already) or if an I/O error occurs. + for (File file : dir.listFiles()) { + addToClasspath(classpath, file); + } + } else { + log(LOG_VERBOSE, "Directory to add in Classpath was not found " + dir.getAbsolutePath()); + } + } catch (SecurityException | NullPointerException e) { + log(LOG_QUIET, e); + } + } + + private void requireCordappsDirExists(File dir) { + try { + if (!dir.mkdir() && !dir.exists()) { // It is unlikely to enter this if-branch, but just in case. + logOnFailedCordappDir(); + throw new RuntimeException("Cordapps dir could not be created"); // Let Capsule handle the error (log error, clean up, die). + } + } + catch (SecurityException | NullPointerException e) { + logOnFailedCordappDir(); + throw e; // Let Capsule handle the error (log error, clean up, die). + } + } + + private void logOnFailedCordappDir() { + log(LOG_VERBOSE, "Cordapps dir could not be created"); + } + + private void addToClasspath(List classpath, File file) { + try { + if (file.canRead()) { if (file.isFile() && isJAR(file)) { classpath.add(file.toPath().toAbsolutePath()); + } else if (file.isDirectory()) { // Search in nested folders as well. TODO: check for circular symlinks. + augmentClasspath(classpath, file); } + } else { + log(LOG_VERBOSE, "File or directory to add in Classpath could not be read " + file.getAbsolutePath()); } + } catch (SecurityException | NullPointerException e) { + log(LOG_QUIET, e); } } @Override protected void liftoff() { super.liftoff(); - Signal.handle(new Signal("INT"), new SignalHandler() { - @Override - public void handle(Signal signal) { - // Disable Ctrl-C for this process, so the child process can handle it in the shell instead. - } + Signal.handle(new Signal("INT"), signal -> { + // Disable Ctrl-C for this process, so the child process can handle it in the shell instead. }); } From 3fb3371d52c5747a1736e8ce3ba5d07e797caa04 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Tue, 24 Apr 2018 19:50:43 +0100 Subject: [PATCH 2/4] Upgrade DemoBench to TornadoFX 1.7.15 (for Kotlin 1.2). (#2998) --- tools/demobench/build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/demobench/build.gradle b/tools/demobench/build.gradle index c0f21ad796..9742b25325 100644 --- a/tools/demobench/build.gradle +++ b/tools/demobench/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.tornadofx_version = '1.7.10' + ext.tornadofx_version = '1.7.15' ext.jna_version = '4.1.0' ext.purejavacomm_version = '0.0.18' ext.controlsfx_version = '8.40.12' @@ -39,6 +39,15 @@ repositories { } } +configurations.all { + resolutionStrategy { + // Force TornadoFX to use the same version of Kotlin as Corda. + force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + force "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + } +} + dependencies { // TornadoFX: A lightweight Kotlin framework for working with JavaFX UI's. compile "no.tornado:tornadofx:$tornadofx_version" From 4cfb1606da39497995ceec89f0f521ff1b0346f0 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 25 Apr 2018 10:38:59 +0200 Subject: [PATCH 3/4] Minor: document the h2port option (#2988) --- docs/source/corda-configuration-file.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/corda-configuration-file.rst b/docs/source/corda-configuration-file.rst index f8e668cea8..d8c10ef1c0 100644 --- a/docs/source/corda-configuration-file.rst +++ b/docs/source/corda-configuration-file.rst @@ -75,6 +75,8 @@ absolute path to the node's base directory. Currently the defaults in ``/node/src/main/resources/reference.conf`` are as shown in the first example. This is currently the only configuration that has been tested, although in the future full support for other storage layers will be validated. +:h2port: A number that's used to pick the H2 JDBC server port. If not set a randomly chosen port will be used. + :messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally. :p2pAddress: The host and port on which the node is available for protocol operations over ArtemisMQ. From 3e27a85fe16cb4b818fbefcf9cf1f1d3429fbc22 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 25 Apr 2018 10:49:23 +0200 Subject: [PATCH 4/4] Minor: mention that h2port is only useful for developer mode in enterprise --- docs/source/corda-configuration-file.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/corda-configuration-file.rst b/docs/source/corda-configuration-file.rst index 4c7a51059c..afc8c3c700 100644 --- a/docs/source/corda-configuration-file.rst +++ b/docs/source/corda-configuration-file.rst @@ -82,7 +82,9 @@ absolute path to the node's base directory. Currently the defaults in ``/node/src/main/resources/reference.conf`` are as shown in the first example. This is currently the only configuration that has been tested, although in the future full support for other storage layers will be validated. -:h2port: A number that's used to pick the H2 JDBC server port. If not set a randomly chosen port will be used. +:h2port: A number that's used to pick the H2 JDBC server port. If not set a randomly chosen port will be used. For production + use you will typically be using a different, non-H2 database backend (e.g. Oracle, SQL Server, Postgres) so this option + is intended primarily for developer mode. :messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally.