Cordapps now contain their own dependencies (#915)

* Cordapps now contain all explicitly specified dependencies (and sub
dependencies).

* Removed some useless compile dependencies for trader demo.

* Dependent Cordapps are excluded from the build.
:Removed unnecessary dependencies of demos.

* Cleaned up exclusion rules for cordapp dependencies.
This commit is contained in:
Clinton
2017-06-30 14:18:46 +01:00
committed by GitHub
parent 82f68f212a
commit c1088038b7
11 changed files with 43 additions and 59 deletions

View File

@ -36,7 +36,7 @@ sourceSets {
} }
processSmokeTestResources { processSmokeTestResources {
from(project(':node:capsule').tasks.buildCordaJAR) { from(project(':node:capsule').tasks['buildCordaJAR']) {
rename 'corda-(.*)', 'corda.jar' rename 'corda-(.*)', 'corda.jar'
} }
} }

View File

@ -1,4 +1,4 @@
gradlePluginsVersion=0.13.0 gradlePluginsVersion=0.13.1
kotlinVersion=1.1.1 kotlinVersion=1.1.1
guavaVersion=21.0 guavaVersion=21.0
bouncycastleVersion=1.57 bouncycastleVersion=1.57

View File

@ -262,22 +262,18 @@ folder has the following structure:
. nodes . nodes
├── controller ├── controller
│   ├── corda.jar │   ├── corda.jar
│   ├── dependencies
│   ├── node.conf │   ├── node.conf
│   └── plugins │   └── plugins
├── nodea ├── nodea
│   ├── corda.jar │   ├── corda.jar
│   ├── dependencies
│   ├── node.conf │   ├── node.conf
│   └── plugins │   └── plugins
├── nodeb ├── nodeb
│   ├── corda.jar │   ├── corda.jar
│   ├── dependencies
│   ├── node.conf │   ├── node.conf
│   └── plugins │   └── plugins
├── nodec ├── nodec
│   ├── corda.jar │   ├── corda.jar
│   ├── dependencies
│   ├── node.conf │   ├── node.conf
│   └── plugins │   └── plugins
├── runnodes ├── runnodes
@ -286,7 +282,7 @@ folder has the following structure:
There will be one folder generated for each node you build (more on later when we get into the detail of the There will be one folder generated for each node you build (more on later when we get into the detail of the
``deployNodes`` Gradle task) and a ``runnodes`` shell script (batch file on Windows). ``deployNodes`` Gradle task) and a ``runnodes`` shell script (batch file on Windows).
Each node folder contains the Corda JAR, a folder for dependencies and a folder for plugins (or CorDapps). There is also Each node folder contains the Corda JAR and a folder for plugins (or CorDapps). There is also
a node.conf file. See :doc:`Corda configuration files <corda-configuration-file>`. a node.conf file. See :doc:`Corda configuration files <corda-configuration-file>`.
**Building from IntelliJ** **Building from IntelliJ**
@ -340,7 +336,6 @@ When booted up, the node will generate a bunch of files and directories in addit
├── cache ├── cache
├── certificates ├── certificates
├── corda.jar ├── corda.jar
├── dependencies
├── identity-private-key ├── identity-private-key
├── identity-public ├── identity-public
├── logs ├── logs

View File

@ -13,6 +13,21 @@ class Cordformation implements Plugin<Project> {
Configuration cordappConf = project.configurations.create("cordapp") Configuration cordappConf = project.configurations.create("cordapp")
cordappConf.transitive = false cordappConf.transitive = false
project.configurations.compile.extendsFrom cordappConf project.configurations.compile.extendsFrom cordappConf
configureCordappJar(project)
}
/**
* Configures this project's JAR as a Cordapp JAR
*/
private void configureCordappJar(Project project) {
// Note: project.afterEvaluate did not have full dependency resolution completed, hence a task is used instead
def task = project.task('configureCordappFatJar') {
doLast {
project.tasks.jar.from getDirectNonCordaDependencies(project).collect { project.zipTree(it) }.flatten()
}
}
project.tasks.jar.dependsOn task
} }
/** /**
@ -27,4 +42,27 @@ class Cordformation implements Plugin<Project> {
it.name.contains('cordformation') it.name.contains('cordformation')
}, filePathInJar).asFile() }, filePathInJar).asFile()
} }
static def getDirectNonCordaDependencies(Project project) {
def coreCordaNames = ['jfx', 'mock', 'rpc', 'core', 'corda', 'cordform-common', 'corda-webserver', 'finance', 'node', 'node-api', 'node-schemas', 'test-utils', 'jackson', 'verifier', 'webserver', 'capsule', 'webcapsule']
def excludes = coreCordaNames.collect { [group: 'net.corda', name: it] } + [
[group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib'],
[group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jre8'],
[group: 'co.paralleluniverse', name: 'quasar-core']
]
// The direct dependencies of this project
def cordappDeps = project.configurations.cordapp.allDependencies
def directDeps = project.configurations.runtime.allDependencies - cordappDeps
// We want to filter out anything Corda related or provided by Corda, like kotlin-stdlib and quasar
def filteredDeps = directDeps.findAll { excludes.collect { exclude -> (exclude.group == it.group) && (exclude.name == it.name) }.findAll { it }.isEmpty() }
filteredDeps.each {
// net.corda may be a core dependency which shouldn't be included in this cordapp so give a warning
if(it.group.contains('net.corda')) {
project.logger.warn("Including a dependency with a net.corda group: $it")
} else {
project.logger.trace("Including dependency: $it")
}
}
return filteredDeps.collect { project.configurations.runtime.files it }.flatten().toSet()
}
} }

View File

@ -104,7 +104,6 @@ class Node extends CordformNode {
installWebserverJar() installWebserverJar()
installBuiltPlugin() installBuiltPlugin()
installCordapps() installCordapps()
installDependencies()
installConfig() installConfig()
} }
@ -172,23 +171,6 @@ class Node extends CordformNode {
} }
} }
/**
* Installs other dependencies to this node's dependencies directory.
*/
private void installDependencies() {
def cordaJar = verifyAndGetCordaJar()
def webJar = verifyAndGetWebserverJar()
def depsDir = new File(nodeDir, "dependencies")
def coreDeps = project.zipTree(cordaJar).getFiles().collect { it.getName() }
def appDeps = project.configurations.runtime.filter {
(it != cordaJar) && (it != webJar) && !project.configurations.cordapp.contains(it) && !coreDeps.contains(it.getName())
}
project.copy {
from appDeps
into depsDir
}
}
/** /**
* Installs the configuration file to this node's directory and detokenises it. * Installs the configuration file to this node's directory and detokenises it.
*/ */

View File

@ -24,8 +24,7 @@ public class CordaCaplet extends Capsule {
// defined as public static final fields on the Capsule class, therefore referential equality is safe. // defined as public static final fields on the Capsule class, therefore referential equality is safe.
if (ATTR_APP_CLASS_PATH == attr) { if (ATTR_APP_CLASS_PATH == attr) {
T cp = super.attribute(attr); T cp = super.attribute(attr);
List<Path> classpath = augmentClasspath((List<Path>) cp, "plugins"); return (T) augmentClasspath((List<Path>) cp, "plugins");
return (T) augmentClasspath(classpath, "dependencies");
} }
return super.attribute(attr); return super.attribute(attr);
} }

View File

@ -30,15 +30,6 @@ dependencies {
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts') compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
compile project(':core') compile project(':core')
compile project(':test-utils') compile project(':test-utils')
// Javax is required for webapis
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
// GraphStream: For visualisation (required by ExampleClientRPC app)
compile "org.graphstream:gs-core:1.3"
compile("org.graphstream:gs-ui:1.3") {
exclude group: "bouncycastle"
}
} }
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {

View File

@ -18,9 +18,6 @@ dependencies {
compile project(':core') compile project(':core')
compile project(':finance') compile project(':finance')
// Javax is required for webapis
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
// Cordapp dependencies // Cordapp dependencies
// GraphStream: For visualisation // GraphStream: For visualisation
compile 'co.paralleluniverse:capsule:1.0.3' compile 'co.paralleluniverse:capsule:1.0.3'

View File

@ -25,9 +25,6 @@ dependencies {
compile project(':client:rpc') compile project(':client:rpc')
compile project(':test-utils') compile project(':test-utils')
compile project(':cordform-common') compile project(':cordform-common')
// Javax is required for webapis
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
} }
idea { idea {

View File

@ -35,9 +35,6 @@ dependencies {
compile project(':webserver') compile project(':webserver')
compile project(':finance') compile project(':finance')
// Javax is required for webapis
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
// Cordapp dependencies // Cordapp dependencies
// Specify your cordapp's dependencies below, including dependent cordapps // Specify your cordapp's dependencies below, including dependent cordapps
compile "com.opengamma.strata:strata-basics:${strata_version}" compile "com.opengamma.strata:strata-basics:${strata_version}"

View File

@ -31,23 +31,11 @@ dependencies {
compile project(':finance') compile project(':finance')
// Corda Plugins: dependent flows and services // Corda Plugins: dependent flows and services
compile project(':samples:bank-of-corda-demo') cordapp project(':samples:bank-of-corda-demo')
// Javax is required for webapis
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
// GraphStream: For visualisation (required by ExampleClientRPC app)
compile "org.graphstream:gs-core:1.3"
compile("org.graphstream:gs-ui:1.3") {
exclude group: "bouncycastle"
}
testCompile project(':test-utils') testCompile project(':test-utils')
testCompile "junit:junit:$junit_version" testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:${assertj_version}" testCompile "org.assertj:assertj-core:${assertj_version}"
// Cordapp dependencies
// Specify your cordapp's dependencies below, including dependent cordapps
} }
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {