corda/core-deterministic/build.gradle
Rick Parker b29713d7b9
ENT-6947 Intern common types to reduce heap footprint (#7239)
ENT-6947: Implement interning for SecureHash, CordaX500Name, PublicKey, AsbtractParty and SignatureAttachmentConstraint, including automatic detection of internable types off companion objects in AMQP & Kyro deserialization.  In some cases, add new factory methods to companion objects, and make main code base use them.

Performance tested in performance cluster with no negative impact visible (so default concurrency setting seems okay).

Testing suggests 5-6x memory saving for tokens in TokensSDK in memory selector.  Should see approx. 1 million tokens per GB or better (1.5 million for the tokens we tested with).
2022-10-18 09:28:41 +01:00

243 lines
7.1 KiB
Groovy

import net.corda.gradle.jarfilter.JarFilterTask
import net.corda.gradle.jarfilter.MetaFixerTask
import proguard.gradle.ProGuardTask
import static org.gradle.api.JavaVersion.VERSION_1_8
plugins {
id 'org.jetbrains.kotlin.jvm'
id 'net.corda.plugins.publish-utils'
id 'com.jfrog.artifactory'
id 'java-library'
id 'idea'
}
apply from: "${rootProject.projectDir}/deterministic.gradle"
description 'Corda core (deterministic)'
evaluationDependsOn(":core")
// required by DJVM and Avian JVM (for running inside the SGX enclave) which only supports Java 8.
targetCompatibility = VERSION_1_8
def javaHome = System.getProperty('java.home')
def jarBaseName = "corda-${project.name}".toString()
configurations {
deterministicLibraries {
canBeConsumed = false
extendsFrom api
}
deterministicArtifacts.extendsFrom deterministicLibraries
}
dependencies {
compileOnly project(':core')
// Configure these by hand. It should be a minimal subset of core's dependencies,
// and without any obviously non-deterministic ones such as Hibernate.
// These "api" dependencies will become "compile" scoped in our published POM.
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api "javax.persistence:javax.persistence-api:2.2"
api "com.google.code.findbugs:jsr305:$jsr305_version"
api "org.slf4j:slf4j-api:$slf4j_version"
// These dependencies will become "runtime" scoped in our published POM.
// See publish.dependenciesFrom.defaultScope.
deterministicLibraries "org.bouncycastle:bcprov-jdk15on:$bouncycastle_version"
deterministicLibraries "org.bouncycastle:bcpkix-jdk15on:$bouncycastle_version"
deterministicLibraries "net.i2p.crypto:eddsa:$eddsa_version"
}
tasks.named('jar', Jar) {
archiveBaseName = 'DOES-NOT-EXIST'
// Don't build a jar here because it would be the wrong one.
// The jar we really want will be built by the metafix task.
enabled = false
}
def coreJarTask = project(':core').tasks.named('jar', Jar)
def originalJar = coreJarTask.map { it.outputs.files.singleFile }
def patchCore = tasks.register('patchCore', Zip) {
dependsOn coreJarTask
destinationDirectory = layout.buildDirectory.dir('source-libs')
metadataCharset 'UTF-8'
archiveClassifier = 'transient'
archiveExtension = 'jar'
from(compileKotlin)
from(processResources)
from(zipTree(originalJar)) {
exclude 'net/corda/core/crypto/DelegatingSecureRandomService*.class'
exclude 'net/corda/core/crypto/DigestSupplier.class'
exclude 'net/corda/core/internal/*ToggleField*.class'
exclude 'net/corda/core/serialization/*SerializationFactory*.class'
exclude 'net/corda/core/serialization/internal/AttachmentsHolderImpl.class'
exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class'
exclude 'net/corda/core/internal/rules/*.class'
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
}
reproducibleFileOrder = true
includeEmptyDirs = false
}
def predeterminise = tasks.register('predeterminise', ProGuardTask) {
injars patchCore
outjars file("$buildDir/proguard/pre-deterministic-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
}
configurations.compileClasspath.forEach {
if (originalJar != it) {
libraryjars it, filter: '!META-INF/versions/**'
}
}
keepattributes '*'
keepdirectories
dontwarn '**$1$1,org.hibernate.annotations.*'
dontpreverify
dontobfuscate
dontoptimize
dontnote
printseeds
verbose
keep '@interface net.corda.core.* { *; }'
keep '@interface net.corda.core.contracts.** { *; }'
keep '@interface net.corda.core.serialization.** { *; }'
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.core.** { public synthetic <methods>; }'
}
def jarFilter = tasks.register('jarFilter', JarFilterTask) {
jars predeterminise
annotations {
forDelete = [
"net.corda.core.DeleteForDJVM"
]
forStub = [
"net.corda.core.StubOutForDJVM"
]
forRemove = [
"co.paralleluniverse.fibers.Suspendable",
"org.hibernate.annotations.Immutable"
]
forSanitise = [
"net.corda.core.DeleteForDJVM"
]
}
}
def determinise = tasks.register('determinise', ProGuardTask) {
injars jarFilter
outjars file("$buildDir/proguard/$jarBaseName-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
}
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
// Analyse the JAR for dead code, and remove (some of) it.
optimizations 'code/removal/simple,code/removal/advanced'
printconfiguration
keepattributes '*'
keepdirectories
dontobfuscate
dontnote
printseeds
verbose
keep '@interface net.corda.core.CordaInternal { *; }'
keep '@interface net.corda.core.DoNotImplement { *; }'
keep '@interface net.corda.core.KeepForDJVM { *; }'
keep '@interface net.corda.core.contracts.** { *; }'
keep '@interface net.corda.core.serialization.** { *; }'
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.core.** { public synthetic <methods>; }'
}
def checkDeterminism = tasks.register('checkDeterminism', ProGuardTask)
def metafix = tasks.register('metafix', MetaFixerTask) {
outputDir = layout.buildDirectory.dir('libs')
jars determinise
suffix ""
// Strip timestamps from the JAR to make it reproducible.
preserveTimestamps = false
finalizedBy checkDeterminism
}
// DOCSTART 01
checkDeterminism.configure {
dependsOn jdkTask
injars metafix
libraryjars deterministic_rt_jar
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
keepattributes '*'
dontpreverify
dontobfuscate
dontoptimize
verbose
keep 'class *'
}
// DOCEND 01
defaultTasks "determinise"
determinise.configure {
finalizedBy metafix
}
tasks.named('assemble') {
dependsOn checkDeterminism
}
def deterministicJar = metafix.map { it.outputs.files.singleFile }
artifacts {
deterministicArtifacts deterministicJar
publish deterministicJar
}
tasks.named('sourceJar', Jar) {
from 'README.md'
include 'README.md'
}
tasks.named('javadocJar', Jar) {
from 'README.md'
include 'README.md'
}
publish {
dependenciesFrom configurations.deterministicArtifacts
name jarBaseName
}
idea {
module {
if (project.hasProperty("deterministic_idea_sdk")) {
jdkName project.property("deterministic_idea_sdk") as String
}
}
}