CORDA-3696: JDK 11 Testing branch (#6131)

* CORDA-3696: Temporary update to enable JDK11 build and test. Will eventually be switchable.

* CORDA-3696: Filter out the Nashorn warning.

* CORDA-3696: Add JDK11 classifier.

* CORDA-3696: Updated match string to cope with JDK11.

* CORDA-3696: Filtering out SPHINCS256_SHA256 where failing due to JDK11.

* CORDA-3696: Now remove SPHINCS256_SHA256 only if JDK11.

* CORDA-3696: Fix test failure - switch to regex matching.

* CORDA-3696: Hide the illegal access warnings.

* CORDA-3696: Check for Java11 when disabling Java11 warnings.

* CORDA-3696: Fix unneccessary non null check.

* CORDA-3696: Reverting build env to JDK8

* CORDA-3696: Revert hiding of illegal access warnings via Unsafe class.

* CORDA-3696: Remove internal access warnings and new JDK11 version checker.

* CORDA-3696: Updated build file for OS

* CORDA-3696: Removed typo

* CORDA-3696: Fixed space typo.

* CORDA-3696: Open modules to remove the illegal access warnings.

Co-authored-by: Adel El-Beik <adelel-beik@19LDN-MAC108.local>
This commit is contained in:
Adel El-Beik 2020-04-16 10:20:30 +01:00 committed by GitHub
parent 2ad996c0bd
commit 27ea570fbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 199 additions and 7 deletions

View File

@ -0,0 +1,83 @@
import static com.r3.build.BuildControl.killAllExistingBuildsForJob
@Library('corda-shared-build-pipeline-steps')
import static com.r3.build.BuildControl.killAllExistingBuildsForJob
killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger())
pipeline {
agent { label 'local-k8s' }
options {
timestamps()
timeout(time: 3, unit: 'HOURS')
}
environment {
DOCKER_TAG_TO_USE = "${env.GIT_COMMIT.subSequence(0, 8)}"
EXECUTOR_NUMBER = "${env.EXECUTOR_NUMBER}"
BUILD_ID = "${env.BUILD_ID}-${env.JOB_NAME}"
ARTIFACTORY_CREDENTIALS = credentials('artifactory-credentials')
}
stages {
stage('Corda Pull Request - Generate Build Image') {
steps {
withCredentials([string(credentialsId: 'container_reg_passwd', variable: 'DOCKER_PUSH_PWD')]) {
sh "./gradlew --no-daemon " +
"-Dkubenetize=true " +
"-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " +
"-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " +
"-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\" " +
"-Ddocker.buildbase.tag=11latest " +
"-Ddocker.dockerfile=DockerfileJDK11Azul" +
" clean pushBuildImage --stacktrace"
}
sh "kubectl auth can-i get pods"
}
}
stage('Corda Pull Request - Run Tests') {
parallel {
stage('Integration Tests') {
steps {
sh "./gradlew --no-daemon " +
"-DbuildId=\"\${BUILD_ID}\" " +
"-Dkubenetize=true " +
"-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " +
"-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " +
"-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " +
"-Dgit.branch=\"\${GIT_BRANCH}\" " +
"-Dgit.target.branch=\"\${CHANGE_TARGET}\" " +
"-Ddependx.branch.origin=${env.GIT_COMMIT} " +
"-Ddependx.branch.target=${CHANGE_TARGET} " +
" allParallelIntegrationTest --stacktrace"
}
}
stage('Unit Tests') {
steps {
sh "./gradlew --no-daemon " +
"-DbuildId=\"\${BUILD_ID}\" " +
"-Dkubenetize=true " +
"-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " +
"-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " +
"-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " +
"-Dgit.branch=\"\${GIT_BRANCH}\" " +
"-Dgit.target.branch=\"\${CHANGE_TARGET}\" " +
"-Ddependx.branch.origin=${env.GIT_COMMIT} " +
"-Ddependx.branch.target=${CHANGE_TARGET} " +
" allParallelUnitTest --stacktrace"
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: '**/pod-logs/**/*.log', fingerprint: false
junit '**/build/test-results-xml/**/*.xml'
}
cleanup {
deleteDir() /* clean up our workspace */
}
}
}

View File

@ -48,6 +48,20 @@ fun checkMinimumPlatformVersion(minimumPlatformVersion: Int, requiredMinPlatform
@Throws(NumberFormatException::class) @Throws(NumberFormatException::class)
fun getJavaUpdateVersion(javaVersion: String): Long = javaVersion.substringAfter("_").substringBefore("-").toLong() fun getJavaUpdateVersion(javaVersion: String): Long = javaVersion.substringAfter("_").substringBefore("-").toLong()
enum class JavaVersion(val versionString: String) {
Java_1_8("1.8"),
Java_11("11");
companion object {
fun isVersionAtLeast(version: JavaVersion): Boolean {
return currentVersion.toFloat() >= version.versionString.toFloat()
}
private val currentVersion: String = System.getProperty("java.specification.version") ?:
throw IllegalStateException("Unable to retrieve system property java.specification.version")
}
}
/** Provide access to internal method for AttachmentClassLoaderTests. */ /** Provide access to internal method for AttachmentClassLoaderTests. */
@DeleteForDJVM @DeleteForDJVM
fun TransactionBuilder.toWireTransaction(services: ServicesForResolution, serializationContext: SerializationContext): WireTransaction { fun TransactionBuilder.toWireTransaction(services: ServicesForResolution, serializationContext: SerializationContext): WireTransaction {

View File

@ -15,6 +15,7 @@ import net.corda.core.crypto.Crypto.generateKeyPair
import net.corda.core.crypto.SignatureScheme import net.corda.core.crypto.SignatureScheme
import net.corda.core.crypto.newSecureRandom import net.corda.core.crypto.newSecureRandom
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.JavaVersion
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
@ -96,6 +97,7 @@ class X509UtilitiesTest {
Pair(ECDSA_SECP256K1_SHA256, RSA_SHA256), Pair(ECDSA_SECP256K1_SHA256, RSA_SHA256),
Pair(EDDSA_ED25519_SHA512, ECDSA_SECP256K1_SHA256), Pair(EDDSA_ED25519_SHA512, ECDSA_SECP256K1_SHA256),
Pair(RSA_SHA256, EDDSA_ED25519_SHA512), Pair(RSA_SHA256, EDDSA_ED25519_SHA512),
Pair(EDDSA_ED25519_SHA512, ECDSA_SECP256R1_SHA256),
Pair(SPHINCS256_SHA256, ECDSA_SECP256R1_SHA256) Pair(SPHINCS256_SHA256, ECDSA_SECP256R1_SHA256)
) )
@ -115,7 +117,8 @@ class X509UtilitiesTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `create valid self-signed CA certificate`() { fun `create valid self-signed CA certificate`() {
Crypto.supportedSignatureSchemes().filter { it != COMPOSITE_KEY }.forEach { validSelfSignedCertificate(it) } Crypto.supportedSignatureSchemes().filter { it != COMPOSITE_KEY
&& ( !JavaVersion.isVersionAtLeast(JavaVersion.Java_11) || it != SPHINCS256_SHA256)}.forEach { validSelfSignedCertificate(it) }
} }
private fun validSelfSignedCertificate(signatureScheme: SignatureScheme) { private fun validSelfSignedCertificate(signatureScheme: SignatureScheme) {
@ -150,7 +153,8 @@ class X509UtilitiesTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `create valid server certificate chain`() { fun `create valid server certificate chain`() {
certChainSchemeCombinations.forEach { createValidServerCertChain(it.first, it.second) } certChainSchemeCombinations.filter{ !JavaVersion.isVersionAtLeast(JavaVersion.Java_11) || it.first != SPHINCS256_SHA256 }
.forEach { createValidServerCertChain(it.first, it.second) }
} }
private fun createValidServerCertChain(signatureSchemeRoot: SignatureScheme, signatureSchemeChild: SignatureScheme) { private fun createValidServerCertChain(signatureSchemeRoot: SignatureScheme, signatureSchemeChild: SignatureScheme) {

View File

@ -79,6 +79,11 @@ task buildCordaJAR(type: FatCapsule, dependsOn: [
manifest { manifest {
// These are the dependencies that the deterministic Corda libraries share with Corda. // These are the dependencies that the deterministic Corda libraries share with Corda.
attributes('Corda-DJVM-Dependencies': cordaResolved.values().collect { it.name }.join(' ')) attributes('Corda-DJVM-Dependencies': cordaResolved.values().collect { it.name }.join(' '))
if (JavaVersion.current() == JavaVersion.VERSION_11) {
attributes('Add-Opens': 'java.management/com.sun.jmx.mbeanserver java.base/java.lang')
}
} }
into('djvm') { into('djvm') {

View File

@ -173,6 +173,27 @@ public class CordaCaplet extends Capsule {
} }
} }
// Capsule does not handle multiple instances of same option hence we add in the args here to process builder
// For multiple instances Capsule jvm args handling works on basis that one overrides the other.
@Override
protected int launch(ProcessBuilder pb) throws IOException, InterruptedException {
if (isAtLeastJavaVersion11()) {
List<String> args = pb.command();
List<String> myArgs = Arrays.asList(
"--add-opens=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED",
"--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.lang.reflect=ALL-UNNAMED",
"--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED",
"--add-opens=java.base/java.time=ALL-UNNAMED",
"--add-opens=java.base/java.io=ALL-UNNAMED",
"--add-opens=java.base/java.nio=ALL-UNNAMED");
args.addAll(1, myArgs);
pb.command(args);
}
return super.launch(pb);
}
/** /**
* Overriding the Caplet classpath generation via the intended interface in Capsule. * Overriding the Caplet classpath generation via the intended interface in Capsule.
*/ */
@ -227,6 +248,9 @@ public class CordaCaplet extends Capsule {
jvmArgs.add("-XX:+HeapDumpOnOutOfMemoryError"); jvmArgs.add("-XX:+HeapDumpOnOutOfMemoryError");
jvmArgs.add("-XX:+CrashOnOutOfMemoryError"); jvmArgs.add("-XX:+CrashOnOutOfMemoryError");
} }
if (isAtLeastJavaVersion11()) {
jvmArgs.add("-Dnashorn.args=--no-deprecation-warning");
}
return (T) jvmArgs; return (T) jvmArgs;
} else if (ATTR_SYSTEM_PROPERTIES == attr) { } else if (ATTR_SYSTEM_PROPERTIES == attr) {
// Add system properties, if specified, from the config. // Add system properties, if specified, from the config.
@ -271,6 +295,14 @@ public class CordaCaplet extends Capsule {
} }
} }
private static boolean isAtLeastJavaVersion11() {
String version = System.getProperty("java.specification.version");
if (version != null) {
return Float.parseFloat(version) >= 11f;
}
return false;
}
private Boolean checkIfCordappDirExists(File dir) { private Boolean checkIfCordappDirExists(File dir) {
try { try {
if (!dir.mkdir() && !dir.exists()) { // It is unlikely to enter this if-branch, but just in case. if (!dir.mkdir() && !dir.exists()) { // It is unlikely to enter this if-branch, but just in case.

View File

@ -5,6 +5,7 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
import org.apache.commons.lang3.SystemUtils
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -14,8 +15,9 @@ class NodeRPCTests {
private val CORDA_VENDOR = "Corda Open Source" private val CORDA_VENDOR = "Corda Open Source"
private val CORDAPPS = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP) private val CORDAPPS = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP)
private val CORDAPP_TYPES = setOf("Contract CorDapp", "Workflow CorDapp") private val CORDAPP_TYPES = setOf("Contract CorDapp", "Workflow CorDapp")
private val CLASSIFIER = if (SystemUtils.IS_JAVA_11) "-jdk11" else ""
private val CORDAPP_CONTRACTS_NAME_REGEX = "corda-finance-contracts-$CORDA_VERSION_REGEX".toRegex() private val CORDAPP_CONTRACTS_NAME_REGEX = "corda-finance-contracts-$CORDA_VERSION_REGEX".toRegex()
private val CORDAPP_WORKFLOWS_NAME_REGEX = "corda-finance-workflows-$CORDA_VERSION_REGEX".toRegex() private val CORDAPP_WORKFLOWS_NAME_REGEX = "corda-finance-workflows-$CORDA_VERSION_REGEX$CLASSIFIER".toRegex()
private val CORDAPP_SHORT_NAME = "Corda Finance Demo" private val CORDAPP_SHORT_NAME = "Corda Finance Demo"
private val CORDAPP_VENDOR = "R3" private val CORDAPP_VENDOR = "R3"
private val CORDAPP_LICENCE = "Open Source (Apache 2)" private val CORDAPP_LICENCE = "Open Source (Apache 2)"

View File

@ -62,7 +62,7 @@ class NonDeterministicContractVerifyTest {
.returnValue.getOrThrow() .returnValue.getOrThrow()
} }
assertThat(ex) assertThat(ex)
.hasMessageStartingWith("NoSuchMethodError: sandbox.java.time.Instant.now()Lsandbox/java/time/Instant;, ") .hasMessageMatching("^NoSuchMethodError: .*\\Qsandbox.java.time.Instant.now()\\E.*\$")
} }
} }
@ -75,7 +75,7 @@ class NonDeterministicContractVerifyTest {
.returnValue.getOrThrow() .returnValue.getOrThrow()
} }
assertThat(ex) assertThat(ex)
.hasMessageStartingWith("NoSuchMethodError: sandbox.java.lang.System.currentTimeMillis()J, ") .hasMessageMatching("^NoSuchMethodError: .*\\Qsandbox.java.lang.System.currentTimeMillis()\\E.*\$")
} }
} }
@ -88,7 +88,7 @@ class NonDeterministicContractVerifyTest {
.returnValue.getOrThrow() .returnValue.getOrThrow()
} }
assertThat(ex) assertThat(ex)
.hasMessageStartingWith("NoSuchMethodError: sandbox.java.lang.System.nanoTime()J, ") .hasMessageMatching("^NoSuchMethodError: .*\\Qsandbox.java.lang.System.nanoTime()\\E.*\$")
} }
} }
@ -101,7 +101,7 @@ class NonDeterministicContractVerifyTest {
.returnValue.getOrThrow() .returnValue.getOrThrow()
} }
assertThat(ex) assertThat(ex)
.hasMessageStartingWith("NoSuchMethodError: sandbox.java.util.UUID.randomUUID()Lsandbox/java/util/UUID;, ") .hasMessageMatching("^NoSuchMethodError: .*\\Qsandbox.java.util.UUID.randomUUID()\\E.*\$")
} }
} }

View File

@ -106,6 +106,12 @@ task runRPCCashIssue(type: JavaExec) {
args 20000 args 20000
args '--currency' args '--currency'
args 'USD' args 'USD'
if (JavaVersion.current() == JavaVersion.VERSION_11) {
jvmArgs '--add-opens'
jvmArgs 'java.base/java.time=ALL-UNNAMED'
jvmArgs '--add-opens'
jvmArgs 'java.base/java.io=ALL-UNNAMED'
}
} }
task runWebCashIssue(type: JavaExec) { task runWebCashIssue(type: JavaExec) {
@ -117,6 +123,12 @@ task runWebCashIssue(type: JavaExec) {
args 30000 args 30000
args '--currency' args '--currency'
args 'GBP' args 'GBP'
if (JavaVersion.current() == JavaVersion.VERSION_11) {
jvmArgs '--add-opens'
jvmArgs 'java.base/java.time=ALL-UNNAMED'
jvmArgs '--add-opens'
jvmArgs 'java.base/java.io=ALL-UNNAMED'
}
} }
jar { jar {

View File

@ -0,0 +1,4 @@
FROM stefanotestingcr.azurecr.io/buildbase:11latest
COPY . /tmp/source
CMD cd /tmp/source && GRADLE_USER_HOME=/tmp/gradle ./gradlew clean testClasses integrationTestClasses --parallel --info

View File

@ -42,6 +42,7 @@ class CordaCliWrapperErrorHandlingTests(val arguments: List<String>, val outputR
val processErrorOutput = BufferedReader( val processErrorOutput = BufferedReader(
InputStreamReader(process.errorStream)) InputStreamReader(process.errorStream))
.lines() .lines()
.filter { !it.startsWith("Warning: Nashorn") }
.collect(Collectors.joining("\n")) .collect(Collectors.joining("\n"))
.toString() .toString()

View File

@ -6,6 +6,7 @@ import com.typesafe.config.*;
import sun.misc.Signal; import sun.misc.Signal;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.*;
@ -86,6 +87,23 @@ public class CordaWebserverCaplet extends Capsule {
return super.prelaunch(jvmArgs, args); return super.prelaunch(jvmArgs, args);
} }
// Capsule does not handle multiple instances of same option hence we add in the args here to process builder
// For multiple instances Capsule jvm args handling works on basis that one overrides the other.
@Override
protected int launch(ProcessBuilder pb) throws IOException, InterruptedException {
if (isAtLeastJavaVersion11()) {
List<String> args = pb.command();
List<String> myArgs = Arrays.asList(
"--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.time=ALL-UNNAMED",
"--add-opens=java.base/java.io=ALL-UNNAMED",
"--add-opens=java.base/java.nio=ALL-UNNAMED");
args.addAll(1, myArgs);
pb.command(args);
}
return super.launch(pb);
}
// Add working directory variable to capsules string replacement variables. // Add working directory variable to capsules string replacement variables.
@Override @Override
protected String getVarValue(String var) { protected String getVarValue(String var) {
@ -139,6 +157,9 @@ public class CordaWebserverCaplet extends Capsule {
} catch (ConfigException e) { } catch (ConfigException e) {
log(LOG_QUIET, e); log(LOG_QUIET, e);
} }
if (isAtLeastJavaVersion11()) {
jvmArgs.add("-Dnashorn.args=--no-deprecation-warning");
}
return (T) jvmArgs; return (T) jvmArgs;
} else if (ATTR_SYSTEM_PROPERTIES == attr) { } else if (ATTR_SYSTEM_PROPERTIES == attr) {
// Add system properties, if specified, from the config. // Add system properties, if specified, from the config.
@ -181,6 +202,14 @@ public class CordaWebserverCaplet extends Capsule {
} }
} }
private static boolean isAtLeastJavaVersion11() {
String version = System.getProperty("java.specification.version");
if (version != null) {
return Float.parseFloat(version) >= 11f;
}
return false;
}
private Boolean checkIfCordappDirExists(File dir) { private Boolean checkIfCordappDirExists(File dir) {
try { try {
if (!dir.mkdir() && !dir.exists()) { // It is unlikely to enter this if-branch, but just in case. if (!dir.mkdir() && !dir.exists()) { // It is unlikely to enter this if-branch, but just in case.

View File

@ -56,6 +56,12 @@ task buildWebserverJar(type: FatCapsule, dependsOn: project(':node').tasks.jar)
// If you change these flags, please also update Driver.kt // If you change these flags, please also update Driver.kt
jvmArgs = ['-Xmx200m', '-XX:+UseG1GC'] jvmArgs = ['-Xmx200m', '-XX:+UseG1GC']
} }
manifest {
if (JavaVersion.current() == JavaVersion.VERSION_11) {
attributes('Add-Opens': 'java.management/com.sun.jmx.mbeanserver java.base/java.lang')
}
}
} }
assemble.dependsOn buildWebserverJar assemble.dependsOn buildWebserverJar