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)
This commit is contained in:
Konstantinos Chalkias 2018-04-24 18:43:07 +01:00 committed by GitHub
parent 5f70b6e049
commit 03fb9d4be2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,8 +4,6 @@
import com.typesafe.config.*; import com.typesafe.config.*;
import sun.misc.Signal; import sun.misc.Signal;
import sun.misc.SignalHandler;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -80,9 +78,11 @@ public class CordaCaplet extends Capsule {
if (ATTR_APP_CLASS_PATH == attr) { if (ATTR_APP_CLASS_PATH == attr) {
T cp = super.attribute(attr); T cp = super.attribute(attr);
(new File(baseDir, "cordapps")).mkdir(); File cordappsDir = new File(baseDir, "cordapps");
// Add additional directories of JARs to the classpath (at the end). e.g. for JDBC drivers // Create cordapps directory if it doesn't exist.
augmentClasspath((List<Path>) cp, new File(baseDir, "cordapps")); requireCordappsDirExists(cordappsDir);
// Add additional directories of JARs to the classpath (at the end), e.g., for JDBC drivers.
augmentClasspath((List<Path>) cp, cordappsDir);
try { try {
List<String> jarDirs = nodeConfig.getStringList("jarDirs"); List<String> jarDirs = nodeConfig.getStringList("jarDirs");
log(LOG_VERBOSE, "Configured JAR directories = " + jarDirs); log(LOG_VERBOSE, "Configured JAR directories = " + jarDirs);
@ -128,24 +128,58 @@ public class CordaCaplet extends Capsule {
} }
private void augmentClasspath(List<Path> classpath, File dir) { private void augmentClasspath(List<Path> classpath, File dir) {
if (dir.exists()) { try {
File[] files = dir.listFiles(); if (dir.exists()) {
for (File file : files) { // 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<Path> classpath, File file) {
try {
if (file.canRead()) {
if (file.isFile() && isJAR(file)) { if (file.isFile() && isJAR(file)) {
classpath.add(file.toPath().toAbsolutePath()); 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 @Override
protected void liftoff() { protected void liftoff() {
super.liftoff(); super.liftoff();
Signal.handle(new Signal("INT"), new SignalHandler() { Signal.handle(new Signal("INT"), signal -> {
@Override // Disable Ctrl-C for this process, so the child process can handle it in the shell instead.
public void handle(Signal signal) {
// Disable Ctrl-C for this process, so the child process can handle it in the shell instead.
}
}); });
} }