From 057ee74611c683fc9aa18647297e30686694cc2e Mon Sep 17 00:00:00 2001 From: Thomas Schroeter Date: Wed, 12 Sep 2018 13:36:04 +0100 Subject: [PATCH 1/4] Single node notary thread safety (#3924) --- .idea/compiler.xml | 2 +- .../notary/AsyncUniquenessProvider.kt | 35 ++++++ .../net/corda/core/node/AppServiceHub.kt | 2 +- .../net/corda/node/internal/AbstractNode.kt | 48 +++++--- .../PersistentUniquenessProvider.kt | 108 ++++++++++++++---- .../transactions/SimpleNotaryService.kt | 4 +- .../transactions/ValidatingNotaryService.kt | 4 +- .../PersistentUniquenessProviderTests.kt | 10 +- .../corda/notarydemo/MyCustomNotaryService.kt | 5 +- 9 files changed, 163 insertions(+), 55 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/internal/notary/AsyncUniquenessProvider.kt diff --git a/.idea/compiler.xml b/.idea/compiler.xml index ef6407f0b3..d981d5fd35 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -235,4 +235,4 @@ - \ No newline at end of file + diff --git a/core/src/main/kotlin/net/corda/core/internal/notary/AsyncUniquenessProvider.kt b/core/src/main/kotlin/net/corda/core/internal/notary/AsyncUniquenessProvider.kt new file mode 100644 index 0000000000..1d9328de88 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/internal/notary/AsyncUniquenessProvider.kt @@ -0,0 +1,35 @@ +package net.corda.core.internal.notary + +import net.corda.core.concurrent.CordaFuture +import net.corda.core.contracts.StateRef +import net.corda.core.contracts.TimeWindow +import net.corda.core.crypto.SecureHash +import net.corda.core.flows.NotarisationRequestSignature +import net.corda.core.flows.NotaryError +import net.corda.core.identity.Party + +/** + * A service that records input states of the given transaction and provides conflict information + * if any of the inputs have already been used in another transaction. + */ +interface AsyncUniquenessProvider : UniquenessProvider { + /** Commits all input states of the given transaction. */ + fun commitAsync(states: List, txId: SecureHash, callerIdentity: Party, requestSignature: NotarisationRequestSignature, timeWindow: TimeWindow?, references: List): CordaFuture + + /** Commits all input states of the given transaction synchronously. Use [commitAsync] for better performance. */ + override fun commit(states: List, txId: SecureHash, callerIdentity: Party, requestSignature: NotarisationRequestSignature, timeWindow: TimeWindow?, references: List) { + val result = commitAsync(states, txId, callerIdentity, requestSignature, timeWindow,references).get() + if (result is Result.Failure) { + throw NotaryInternalException(result.error) + } + } + + /** The outcome of committing a transaction. */ + sealed class Result { + /** Indicates that all input states have been committed successfully. */ + object Success : Result() + /** Indicates that the transaction has not been committed. */ + data class Failure(val error: NotaryError) : Result() + } +} + diff --git a/core/src/main/kotlin/net/corda/core/node/AppServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/AppServiceHub.kt index 62e5e2f1f6..60816009cb 100644 --- a/core/src/main/kotlin/net/corda/core/node/AppServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/AppServiceHub.kt @@ -28,4 +28,4 @@ interface AppServiceHub : ServiceHub { * TODO it is assumed here that the flow object has an appropriate classloader. */ fun startTrackedFlow(flow: FlowLogic): FlowProgressHandle -} \ No newline at end of file +} diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index cb008ac462..5590c1fe74 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -521,7 +521,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } /** - * If the [serviceClass] is a notary service, it will only be enable if the "custom" flag is set in + * If the [serviceClass] is a notary service, it will only be enabled if the "custom" flag is set in * the notary configuration. */ private fun isNotaryService(serviceClass: Class<*>) = NotaryService::class.java.isAssignableFrom(serviceClass) @@ -568,28 +568,38 @@ abstract class AbstractNode(val configuration: NodeConfiguration, private fun installCordaService(flowStarter: FlowStarter, serviceClass: Class, myNotaryIdentity: PartyAndCertificate?) { serviceClass.requireAnnotation() + val service = try { - val serviceContext = AppServiceHubImpl(services, flowStarter) - if (isNotaryService(serviceClass)) { - myNotaryIdentity ?: throw IllegalStateException("Trying to install a notary service but no notary identity specified") - val constructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java, PublicKey::class.java).apply { isAccessible = true } - serviceContext.serviceInstance = constructor.newInstance(serviceContext, myNotaryIdentity.owningKey) - serviceContext.serviceInstance - } else { - try { - val extendedServiceConstructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java).apply { isAccessible = true } - serviceContext.serviceInstance = extendedServiceConstructor.newInstance(serviceContext) - serviceContext.serviceInstance - } catch (ex: NoSuchMethodException) { - val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true } - log.warn("${serviceClass.name} is using legacy CordaService constructor with ServiceHub parameter. " + - "Upgrade to an AppServiceHub parameter to enable updated API features.") - constructor.newInstance(services) - } - } + if (isNotaryService(serviceClass)) { + myNotaryIdentity ?: throw IllegalStateException("Trying to install a notary service but no notary identity specified") + try { + val constructor = serviceClass.getDeclaredConstructor(ServiceHubInternal::class.java, PublicKey::class.java).apply { isAccessible = true } + constructor.newInstance(services, myNotaryIdentity.owningKey ) + } catch (ex: NoSuchMethodException) { + val constructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java, PublicKey::class.java).apply { isAccessible = true } + val serviceContext = AppServiceHubImpl(services, flowStarter) + val service = constructor.newInstance(serviceContext, myNotaryIdentity.owningKey) + serviceContext.serviceInstance = service + service + } + } else { + try { + val serviceContext = AppServiceHubImpl(services, flowStarter) + val extendedServiceConstructor = serviceClass.getDeclaredConstructor(AppServiceHub::class.java).apply { isAccessible = true } + val service = extendedServiceConstructor.newInstance(serviceContext) + serviceContext.serviceInstance = service + service + } catch (ex: NoSuchMethodException) { + val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true } + log.warn("${serviceClass.name} is using legacy CordaService constructor with ServiceHub parameter. " + + "Upgrade to an AppServiceHub parameter to enable updated API features.") + constructor.newInstance(services) + } + } } catch (e: InvocationTargetException) { throw ServiceInstantiationException(e.cause) } + cordappServices.putInstance(serviceClass, service) if (service is NotaryService) handleCustomNotaryService(service) diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt b/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt index e0ab98b9e5..eadedd4e64 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt @@ -1,5 +1,6 @@ package net.corda.node.services.transactions +import net.corda.core.concurrent.CordaFuture import net.corda.core.contracts.StateRef import net.corda.core.contracts.TimeWindow import net.corda.core.crypto.SecureHash @@ -8,11 +9,9 @@ import net.corda.core.flows.NotarisationRequestSignature import net.corda.core.flows.NotaryError import net.corda.core.flows.StateConsumptionDetails import net.corda.core.identity.Party -import net.corda.core.internal.ThreadBox -import net.corda.core.internal.notary.NotaryInternalException -import net.corda.core.internal.notary.UniquenessProvider -import net.corda.core.internal.notary.isConsumedByTheSameTx -import net.corda.core.internal.notary.validateTimeWindow +import net.corda.core.internal.concurrent.OpenFuture +import net.corda.core.internal.concurrent.openFuture +import net.corda.core.internal.notary.* import net.corda.core.schemas.PersistentStateRef import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SingletonSerializeAsToken @@ -20,17 +19,22 @@ import net.corda.core.serialization.serialize import net.corda.core.utilities.contextLogger import net.corda.core.utilities.debug import net.corda.node.utilities.AppendOnlyPersistentMap +import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX import net.corda.nodeapi.internal.persistence.currentDBSession +import net.corda.serialization.internal.CordaSerializationEncoding import java.time.Clock import java.time.Instant import java.util.* +import java.util.concurrent.LinkedBlockingQueue import javax.annotation.concurrent.ThreadSafe import javax.persistence.* +import kotlin.concurrent.thread /** A RDBMS backed Uniqueness provider */ @ThreadSafe -class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, SingletonSerializeAsToken() { +class PersistentUniquenessProvider(val clock: Clock, val database: CordaPersistence) : AsyncUniquenessProvider, SingletonSerializeAsToken() { + @MappedSuperclass class BaseComittedState( @EmbeddedId @@ -63,17 +67,36 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl var requestDate: Instant ) + private data class CommitRequest( + val states: List, + val txId: SecureHash, + val callerIdentity: Party, + val requestSignature: NotarisationRequestSignature, + val timeWindow: TimeWindow?, + val references: List, + val future: OpenFuture) + @Entity @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}notary_committed_states") class CommittedState(id: PersistentStateRef, consumingTxHash: String) : BaseComittedState(id, consumingTxHash) - private class InnerState { - val commitLog = createMap() + private val commitLog = createMap() + + private val requestQueue = LinkedBlockingQueue(requestQueueSize) + + /** A request processor thread. */ + private val processorThread = thread(name = "Notary request queue processor", isDaemon = true) { + try { + while (!Thread.interrupted()) { + processRequest(requestQueue.take()) + } + } catch (e: InterruptedException) { + } + log.debug { "Shutting down with ${requestQueue.size} in-flight requests unprocessed." } } - private val mutex = ThreadBox(InnerState()) - companion object { + private const val requestQueueSize = 100_000 private val log = contextLogger() fun createMap(): AppendOnlyPersistentMap = AppendOnlyPersistentMap( @@ -99,23 +122,25 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl ) } - override fun commit( + + /** + * Generates and adds a [CommitRequest] to the request queue. If the request queue is full, this method will block + * until space is available. + * + * Returns a future that will complete once the request is processed, containing the commit [Result]. + */ + override fun commitAsync( states: List, txId: SecureHash, callerIdentity: Party, requestSignature: NotarisationRequestSignature, timeWindow: TimeWindow?, references: List - ) { - mutex.locked { - logRequest(txId, callerIdentity, requestSignature) - val conflictingStates = findAlreadyCommitted(states, references, commitLog) - if (conflictingStates.isNotEmpty()) { - handleConflicts(txId, conflictingStates) - } else { - handleNoConflicts(timeWindow, states, txId, commitLog) - } - } + ): CordaFuture { + val future = openFuture() + val request = CommitRequest(states, txId, callerIdentity, requestSignature, timeWindow, references, future) + requestQueue.put(request) + return future } private fun logRequest(txId: SecureHash, callerIdentity: Party, requestSignature: NotarisationRequestSignature) { @@ -149,6 +174,25 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl return conflictingStates } + private fun commitOne( + states: List, + txId: SecureHash, + callerIdentity: Party, + requestSignature: NotarisationRequestSignature, + timeWindow: TimeWindow?, + references: List + ) { + database.transaction { + logRequest(txId, callerIdentity, requestSignature) + val conflictingStates = findAlreadyCommitted(states, references, commitLog) + if (conflictingStates.isNotEmpty()) { + handleConflicts(txId, conflictingStates) + } else { + handleNoConflicts(timeWindow, states, txId, commitLog) + } + } + } + private fun handleConflicts(txId: SecureHash, conflictingStates: LinkedHashMap) { if (isConsumedByTheSameTx(txId.sha256(), conflictingStates)) { log.debug { "Transaction $txId already notarised" } @@ -171,4 +215,26 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl throw NotaryInternalException(outsideTimeWindowError) } } + + private fun processRequest(request: CommitRequest) { + try { + commitOne(request.states, request.txId, request.callerIdentity, request.requestSignature, request.timeWindow, request.references) + respondWithSuccess(request) + } catch (e: Exception) { + log.warn("Error processing commit request", e) + respondWithError(request, e) + } + } + + private fun respondWithError(request: CommitRequest, exception: Exception) { + if (exception is NotaryInternalException) { + request.future.set(AsyncUniquenessProvider.Result.Failure(exception.error)) + } else { + request.future.setException(NotaryInternalException(NotaryError.General(Exception("Internal service error.")))) + } + } + + private fun respondWithSuccess(request: CommitRequest) { + request.future.set(AsyncUniquenessProvider.Result.Success) + } } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt index 093c0d905b..16ad4464af 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt @@ -8,10 +8,10 @@ import java.security.PublicKey /** A simple Notary service that does not perform transaction validation */ class SimpleNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { - override val uniquenessProvider = PersistentUniquenessProvider(services.clock) + override val uniquenessProvider = PersistentUniquenessProvider(services.clock, services.database) override fun createServiceFlow(otherPartySession: FlowSession): NotaryServiceFlow = NonValidatingNotaryFlow(otherPartySession, this) override fun start() {} override fun stop() {} -} \ No newline at end of file +} diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt index 08b4fcb211..4a6f46b2ce 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt @@ -8,10 +8,10 @@ import java.security.PublicKey /** A Notary service that validates the transaction chain of the submitted transaction before committing it */ class ValidatingNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { - override val uniquenessProvider = PersistentUniquenessProvider(services.clock) + override val uniquenessProvider = PersistentUniquenessProvider(services.clock, services.database) override fun createServiceFlow(otherPartySession: FlowSession): NotaryServiceFlow = ValidatingNotaryFlow(otherPartySession, this) override fun start() {} override fun stop() {} -} \ No newline at end of file +} diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt index 17fe106c99..bdc2b642d0 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt @@ -28,7 +28,7 @@ import kotlin.test.assertFailsWith class PersistentUniquenessProviderTests { @Rule @JvmField - val testSerialization = SerializationEnvironmentRule() + val testSerialization = SerializationEnvironmentRule(inheritable = true) private val identity = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party private val txID = SecureHash.randomSHA256() private val requestSignature = NotarisationRequestSignature(DigitalSignature.WithKey(NullKeys.NullPublicKey, ByteArray(32)), 0) @@ -49,18 +49,15 @@ class PersistentUniquenessProviderTests { @Test fun `should commit a transaction with unused inputs without exception`() { - database.transaction { - val provider = PersistentUniquenessProvider(Clock.systemUTC()) + val provider = PersistentUniquenessProvider(Clock.systemUTC(), database) val inputState = generateStateRef() provider.commit(listOf(inputState), txID, identity, requestSignature) - } } @Test fun `should report a conflict for a transaction with previously used inputs`() { - database.transaction { - val provider = PersistentUniquenessProvider(Clock.systemUTC()) + val provider = PersistentUniquenessProvider(Clock.systemUTC(), database) val inputState = generateStateRef() val inputs = listOf(inputState) @@ -76,5 +73,4 @@ class PersistentUniquenessProviderTests { val conflictCause = error.consumedStates[inputState]!! assertEquals(conflictCause.hashOfTransactionId, firstTxId.sha256()) } - } } diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/MyCustomNotaryService.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/MyCustomNotaryService.kt index dd1f424d1d..666844691c 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/MyCustomNotaryService.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/MyCustomNotaryService.kt @@ -13,6 +13,7 @@ import net.corda.core.node.services.CordaService import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionWithSignatures import net.corda.core.transactions.WireTransaction +import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.transactions.PersistentUniquenessProvider import java.security.PublicKey import java.security.SignatureException @@ -25,8 +26,8 @@ import java.security.SignatureException */ // START 1 @CordaService -class MyCustomValidatingNotaryService(override val services: AppServiceHub, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { - override val uniquenessProvider = PersistentUniquenessProvider(services.clock) +class MyCustomValidatingNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { + override val uniquenessProvider = PersistentUniquenessProvider(services.clock, services.database) override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic = MyValidatingNotaryFlow(otherPartySession, this) From 0c1910722b4d88182b62406431321c20a15262ec Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Thu, 13 Sep 2018 09:16:24 +0100 Subject: [PATCH 2/4] ENT-2489: Gracefully handle session that might have already been closed. (#3933) --- .../net/corda/nodeapi/internal/ArtemisMessagingClient.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/ArtemisMessagingClient.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ArtemisMessagingClient.kt index 4af839bc13..e7b57d10f1 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/ArtemisMessagingClient.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ArtemisMessagingClient.kt @@ -58,8 +58,11 @@ class ArtemisMessagingClient(private val config: MutualSslConfiguration, override fun stop() = synchronized(this) { started?.run { producer.close() - // Ensure any trailing messages are committed to the journal - session.commit() + // Since we are leaking the session outside of this class it may well be already closed. + if(!session.isClosed) { + // Ensure any trailing messages are committed to the journal + session.commit() + } // Closing the factory closes all the sessions it produced as well. sessionFactory.close() } From 1c7dfd4b7b310e86b8aa973b8350487ba63c08b1 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Thu, 13 Sep 2018 10:55:52 +0100 Subject: [PATCH 3/4] CORDA-1964: Unify versioning of the shadow plugin, and resolve more issues for Gradle 5.0. (#3918) --- build.gradle | 4 ++- djvm/build.gradle | 2 +- experimental/avalanche/build.gradle | 19 ++++------ node/build.gradle | 5 +++ tools/demobench/build.gradle | 34 +++++++++--------- tools/explorer/build.gradle | 5 +++ tools/network-bootstrapper/build.gradle | 47 ++++++++++++------------- tools/shell-cli/build.gradle | 9 ----- 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/build.gradle b/build.gradle index ed6188c746..992a8509c3 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,6 @@ buildscript { ext.crash_version = 'cadb53544fbb3c0fb901445da614998a6a419488' ext.jsr305_version = constants.getProperty("jsr305Version") ext.shiro_version = '1.4.0' - ext.shadow_version = '2.0.4' ext.artifactory_plugin_version = constants.getProperty('artifactoryPluginVersion') ext.liquibase_version = '3.5.5' ext.artifactory_contextUrl = 'https://ci-artifactory.corda.r3cev.com/artifactory' @@ -117,6 +116,9 @@ plugins { // but the DSL has some restrictions e.g can't be used on the allprojects section. So we should revisit this if there are improvements in Gradle. // Version 1.0.2 of this plugin uses capsule:1.0.1 id "us.kirchmeier.capsule" version "1.0.2" + + // Add the shadow plugin to the plugins classpath for the entire project. + id 'com.github.johnrengelman.shadow' version '2.0.4' apply false } ext { diff --git a/djvm/build.gradle b/djvm/build.gradle index 2cf5b11d72..f1a621b012 100644 --- a/djvm/build.gradle +++ b/djvm/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.github.johnrengelman.shadow' version '2.0.4' + id 'com.github.johnrengelman.shadow' } apply plugin: 'net.corda.plugins.publish-utils' apply plugin: 'com.jfrog.artifactory' diff --git a/experimental/avalanche/build.gradle b/experimental/avalanche/build.gradle index 82cfd5135d..2e7c1970ec 100644 --- a/experimental/avalanche/build.gradle +++ b/experimental/avalanche/build.gradle @@ -1,24 +1,19 @@ -buildscript { - repositories { - jcenter() - } - - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" - } -} - apply plugin: 'kotlin' apply plugin: 'application' +// We need to set mainClassName before applying the shadow plugin. +mainClassName = "net.corda.avalanche.MainKt" + apply plugin: 'com.github.johnrengelman.shadow' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - compile "info.picocli:picocli:3.0.1" + compile "info.picocli:picocli:$picocli_version" testCompile "junit:junit:$junit_version" } -mainClassName = "net.corda.avalanche.MainKt" +jar.enabled = false + shadowJar { baseName = "avalanche" } +assemble.dependsOn shadowJar diff --git a/node/build.gradle b/node/build.gradle index a562c603d2..bc270b7b7b 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -191,6 +191,11 @@ dependencies { compile "com.palominolabs.metrics:metrics-new-relic:${metrics_new_relic_version}" } +tasks.withType(JavaCompile) { + // Resolves a Gradle warning about not scanning for pre-processors. + options.compilerArgs << '-proc:none' +} + task integrationTest(type: Test) { testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath diff --git a/tools/demobench/build.gradle b/tools/demobench/build.gradle index 2dbc5c941a..c22547dbea 100644 --- a/tools/demobench/build.gradle +++ b/tools/demobench/build.gradle @@ -1,22 +1,15 @@ -buildscript { - ext { - tornadofx_version = '1.7.15' - jna_version = '4.1.0' - purejavacomm_version = '0.0.18' - controlsfx_version = '8.40.12' +ext { + tornadofx_version = '1.7.15' + jna_version = '4.1.0' + purejavacomm_version = '0.0.18' + controlsfx_version = '8.40.12' - java_home = System.properties.'java.home' - pkg_source = "$buildDir/packagesrc" - pkg_outDir = "$buildDir/javapackage" - dist_source = "$pkg_source/demobench-$version" - pkg_version = version.indexOf('-') >= 0 ? version.substring(0, version.indexOf('-')) : version - pkg_macosxKeyUserName = 'R3CEV' - } - - repositories { - mavenLocal() - mavenCentral() - } + java_home = System.properties.'java.home' + pkg_source = "$buildDir/packagesrc" + pkg_outDir = "$buildDir/javapackage" + dist_source = "$pkg_source/demobench-$version" + pkg_version = version.indexOf('-') >= 0 ? version.substring(0, version.indexOf('-')) : version + pkg_macosxKeyUserName = 'R3CEV' } apply plugin: 'java' @@ -84,6 +77,11 @@ dependencies { testCompile "org.assertj:assertj-core:$assertj_version" } +tasks.withType(JavaCompile) { + // Resolves a Gradle warning about not scanning for pre-processors. + options.compilerArgs << '-proc:none' +} + jar { manifest { attributes( diff --git a/tools/explorer/build.gradle b/tools/explorer/build.gradle index 05517cc7ca..fe52056591 100644 --- a/tools/explorer/build.gradle +++ b/tools/explorer/build.gradle @@ -57,6 +57,11 @@ dependencies { compile 'com.yuvimasory:orange-extensions:1.3.0' } +tasks.withType(JavaCompile) { + // Resolves a Gradle warning about not scanning for pre-processors. + options.compilerArgs << '-proc:none' +} + task runDemoNodes(dependsOn: 'classes', type: JavaExec) { main = 'net.corda.explorer.MainKt' classpath = sourceSets.main.runtimeClasspath diff --git a/tools/network-bootstrapper/build.gradle b/tools/network-bootstrapper/build.gradle index f7bc85a9de..674b97f229 100644 --- a/tools/network-bootstrapper/build.gradle +++ b/tools/network-bootstrapper/build.gradle @@ -1,26 +1,24 @@ -buildscript { - - ext.tornadofx_version = '1.7.15' - ext.controlsfx_version = '8.40.12' - - - repositories { - mavenLocal() - mavenCentral() - jcenter() - } - - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" - } +ext { + tornadofx_version = '1.7.15' + controlsfx_version = '8.40.12' } apply plugin: 'kotlin' apply plugin: 'idea' apply plugin: 'java' apply plugin: 'application' +// We need to set mainClassName before applying the shadow plugin. +mainClassName = 'net.corda.bootstrapper.Main' + apply plugin: 'com.github.johnrengelman.shadow' +configurations { + compile { + exclude group: "log4j", module: "log4j" + exclude group: "org.apache.logging.log4j" + } +} + dependencies { compile "com.microsoft.azure:azure:1.8.0" compile "com.github.docker-java:docker-java:3.0.6" @@ -35,7 +33,7 @@ dependencies { compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version" - compile 'info.picocli:picocli:3.0.1' + compile "info.picocli:picocli:$picocli_version" // TornadoFX: A lightweight Kotlin framework for working with JavaFX UI's. compile "no.tornado:tornadofx:$tornadofx_version" @@ -44,18 +42,19 @@ dependencies { compile "org.controlsfx:controlsfx:$controlsfx_version" } +tasks.withType(JavaCompile) { + // Resolves a Gradle warning about not scanning for pre-processors. + options.compilerArgs << '-proc:none' +} + +jar.enabled = false + shadowJar { baseName = 'network-bootstrapper' classifier = null version = null zip64 true - mainClassName = 'net.corda.bootstrapper.Main' } -task buildNetworkBootstrapper(dependsOn: shadowJar) { -} - -configurations { - compile.exclude group: "log4j", module: "log4j" - compile.exclude group: "org.apache.logging.log4j" -} \ No newline at end of file +task buildNetworkBootstrapper(dependsOn: shadowJar) +assemble.dependsOn buildNetworkBootstrapper diff --git a/tools/shell-cli/build.gradle b/tools/shell-cli/build.gradle index d4d510e4cb..89a74f394c 100644 --- a/tools/shell-cli/build.gradle +++ b/tools/shell-cli/build.gradle @@ -1,14 +1,5 @@ description 'Corda Shell CLI' -buildscript { - repositories { - gradlePluginPortal() - } - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" - } -} - apply plugin: 'application' // We need to set mainClassName before applying the shadow plugin. mainClassName = 'net.corda.tools.shell.StandaloneShellKt' From fba96a53fa74ea500fc86f980daaaf28171fa4fb Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Thu, 13 Sep 2018 11:42:58 +0100 Subject: [PATCH 4/4] Update remaining shadow plugin usages, remove cordform-common from,node. --- node-api/build.gradle | 2 +- node/build.gradle | 3 --- tools/dbmigration/build.gradle | 32 ++++++++++++++------------------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/node-api/build.gradle b/node-api/build.gradle index 779817a752..8bd131c237 100644 --- a/node-api/build.gradle +++ b/node-api/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "2.0.4" + id 'com.github.johnrengelman.shadow' } apply plugin: 'kotlin' apply plugin: 'net.corda.plugins.quasar-utils' diff --git a/node/build.gradle b/node/build.gradle index bec73872df..42669e0dc6 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -73,9 +73,6 @@ dependencies { compile project(':tools:shell') compile project(':tools:cliutils') - - compile "net.corda.plugins:cordform-common:$gradle_plugins_version" - // Log4J: logging framework (with SLF4J bindings) compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" compile "org.apache.logging.log4j:log4j-web:${log4j_version}" diff --git a/tools/dbmigration/build.gradle b/tools/dbmigration/build.gradle index ab740ee570..4789d59a99 100644 --- a/tools/dbmigration/build.gradle +++ b/tools/dbmigration/build.gradle @@ -1,45 +1,41 @@ -description 'Database Migration Tool' - -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" - classpath 'de.sebastianboegl.gradle.plugins:shadow-log4j-transformer:2.1.1' - } +plugins { + id 'de.sebastianboegl.shadow.transformer.log4j' version '2.1.1' apply false } +description 'Database Migration Tool' + apply plugin: 'application' +// We need to set mainClassName before applying the shadow plugin. +mainClassName = 'com.r3.corda.dbmigration.DBMigration' + apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'net.corda.plugins.publish-utils' apply plugin: 'com.jfrog.artifactory' -mainClassName = 'com.r3.corda.dbmigration.DBMigration' - dependencies { compile project(':node') // JOpt: for command line flags. compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" } +import de.sebastianboegl.gradle.plugins.shadow.transformers.Log4j2PluginsFileTransformer shadowJar { - transform(de.sebastianboegl.gradle.plugins.shadow.transformers.Log4j2PluginsFileTransformer) - archiveName = "database-manager-${version}.jar" + transform(Log4j2PluginsFileTransformer) + baseName = 'database-manager' } task buildMigrationTool(dependsOn: shadowJar) +assemble.dependsOn buildMigrationTool artifacts { publish shadowJar { - classifier "" + classifier = '' } } jar { - classifier "ignore" + classifier 'ignore' + enabled = false } publish {