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 {
from(project(':node:capsule').tasks.buildCordaJAR) {
from(project(':node:capsule').tasks['buildCordaJAR']) {
rename 'corda-(.*)', 'corda.jar'
}
}

View File

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

View File

@ -262,22 +262,18 @@ folder has the following structure:
. nodes
├── controller
│   ├── corda.jar
│   ├── dependencies
│   ├── node.conf
│   └── plugins
├── nodea
│   ├── corda.jar
│   ├── dependencies
│   ├── node.conf
│   └── plugins
├── nodeb
│   ├── corda.jar
│   ├── dependencies
│   ├── node.conf
│   └── plugins
├── nodec
│   ├── corda.jar
│   ├── dependencies
│   ├── node.conf
│   └── plugins
├── 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
``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>`.
**Building from IntelliJ**
@ -340,7 +336,6 @@ When booted up, the node will generate a bunch of files and directories in addit
├── cache
├── certificates
├── corda.jar
├── dependencies
├── identity-private-key
├── identity-public
├── logs

View File

@ -13,6 +13,21 @@ class Cordformation implements Plugin<Project> {
Configuration cordappConf = project.configurations.create("cordapp")
cordappConf.transitive = false
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')
}, 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()
installBuiltPlugin()
installCordapps()
installDependencies()
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.
*/

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.
if (ATTR_APP_CLASS_PATH == attr) {
T cp = super.attribute(attr);
List<Path> classpath = augmentClasspath((List<Path>) cp, "plugins");
return (T) augmentClasspath(classpath, "dependencies");
return (T) augmentClasspath((List<Path>) cp, "plugins");
}
return super.attribute(attr);
}

View File

@ -30,15 +30,6 @@ dependencies {
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
compile project(':core')
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']) {

View File

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

View File

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

View File

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

View File

@ -31,23 +31,11 @@ dependencies {
compile project(':finance')
// Corda Plugins: dependent flows and services
compile 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"
}
cordapp project(':samples:bank-of-corda-demo')
testCompile project(':test-utils')
testCompile "junit:junit:$junit_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']) {