From 900809b3d74f9e45e5b34932b17c859f15a42ce8 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Fri, 1 Mar 2024 17:23:23 +0000 Subject: [PATCH] ENT-11090: Removed all JDK 8/11 conditional code --- build.gradle | 1 - .../jackson/StringToMethodCallParser.kt | 4 +- constants.properties | 1 - core/build.gradle | 1 - .../corda/core/internal/ClassLoadingUtils.kt | 41 +++++++++---------- .../net/corda/core/internal/CordaUtils.kt | 20 +-------- node-api/build.gradle | 1 - .../kryo/CordaClosureSerializer.kt | 8 ---- .../internal/serialization/kryo/KryoTests.kt | 14 ++----- .../node/amqp/AMQPClientSslErrorsTest.kt | 19 +++------ .../net/corda/node/internal/AbstractNode.kt | 3 -- .../kotlin/net/corda/node/internal/Node.kt | 15 +------ .../net/corda/node/internal/NodeStartup.kt | 2 - .../services/events/NodeSchedulerService.kt | 2 +- .../node/services/statemachine/FlowCreator.kt | 2 +- .../net/corda/node/internal/NodeTest.kt | 19 ++------- .../corda/node/utilities/ClockUtilsTest.kt | 36 ++++++++-------- .../internal/amqp/SerializationOutputTests.kt | 39 ++++++------------ .../internal/amqp/ObjectBuilder.kt | 12 ++---- .../testing/node/internal/NodeBasedTest.kt | 19 ++++----- .../kotlin/net/corda/webserver/WebServer.kt | 2 - 21 files changed, 78 insertions(+), 183 deletions(-) diff --git a/build.gradle b/build.gradle index 34fe923b28..7626b91725 100644 --- a/build.gradle +++ b/build.gradle @@ -259,7 +259,6 @@ allprojects { targetCompatibility = VERSION_17 jacoco { - // JDK11 official support (https://github.com/jacoco/jacoco/releases/tag/v0.8.3) toolVersion = "0.8.7" } diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt index 7b9a1dec27..4d95662140 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt @@ -120,7 +120,7 @@ open class StringToMethodCallParser @JvmOverloads constructor( } /** - * Uses either Kotlin or Java 8 reflection to learn the names of the parameters to a method. + * Uses either Kotlin or Java reflection to learn the names of the parameters to a method. */ open fun paramNamesFromMethod(method: Method): List { val kf: KFunction<*>? = method.kotlinFunction @@ -135,7 +135,7 @@ open class StringToMethodCallParser @JvmOverloads constructor( } /** - * Uses either Kotlin or Java 8 reflection to learn the names of the parameters to a constructor. + * Uses either Kotlin or Java reflection to learn the names of the parameters to a constructor. */ open fun paramNamesFromConstructor(ctor: Constructor<*>): List { val kf: KFunction<*>? = ctor.kotlinFunction diff --git a/constants.properties b/constants.properties index efd2246e17..8a7ae4f0fb 100644 --- a/constants.properties +++ b/constants.properties @@ -17,7 +17,6 @@ platformVersion=140 openTelemetryVersion=1.20.1 openTelemetrySemConvVersion=1.20.1-alpha guavaVersion=28.0-jre -# Quasar version to use with Java 8: quasarVersion=0.9.0_r3 dockerJavaVersion=3.2.5 proguardVersion=7.3.1 diff --git a/core/build.gradle b/core/build.gradle index b1c5e1d7dd..68d4084526 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -58,7 +58,6 @@ dependencies { testImplementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastle_version" testImplementation "org.ow2.asm:asm:$asm_version" - // JDK11: required by Quasar at run-time testRuntimeOnly "com.esotericsoftware:kryo:$kryo_version" testRuntimeOnly "org.slf4j:slf4j-simple:$slf4j_version" diff --git a/core/src/main/kotlin/net/corda/core/internal/ClassLoadingUtils.kt b/core/src/main/kotlin/net/corda/core/internal/ClassLoadingUtils.kt index 4b1fe0b291..2891a7a7fb 100644 --- a/core/src/main/kotlin/net/corda/core/internal/ClassLoadingUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/ClassLoadingUtils.kt @@ -33,30 +33,27 @@ fun createInstancesOfClassesImplementing(classloader: ClassLoader, claz * @return names of the identified classes. * @throws UnsupportedClassVersionError if the class version is not within range. */ -fun getNamesOfClassesImplementing(classloader: ClassLoader, clazz: Class, - classVersionRange: IntRange? = null): Set { - val isJava11 = JavaVersion.isVersionAtLeast(JavaVersion.Java_11) - - return ClassGraph().apply { - if (!isJava11 || classloader !== ClassLoader.getSystemClassLoader()) { - overrideClassLoaders(classloader) - } - } - .enableURLScheme(attachmentScheme) - .ignoreParentClassLoaders() - .enableClassInfo() - .pooledScan() - .use { result -> - classVersionRange?.let { - result.allClasses.firstOrNull { c -> c.classfileMajorVersion !in classVersionRange }?.also { - throw UnsupportedClassVersionError("Class ${it.name} found in ${it.classpathElementURL} " + - "has an unsupported class version of ${it.classfileMajorVersion}") +fun getNamesOfClassesImplementing(classloader: ClassLoader, clazz: Class, classVersionRange: IntRange? = null): Set { + val classGraph = ClassGraph() + if (classloader !== ClassLoader.getSystemClassLoader()) { + classGraph.overrideClassLoaders(classloader) + } + return classGraph + .enableURLScheme(attachmentScheme) + .ignoreParentClassLoaders() + .enableClassInfo() + .pooledScan() + .use { result -> + classVersionRange?.let { + result.allClasses.firstOrNull { c -> c.classfileMajorVersion !in classVersionRange }?.also { + throw UnsupportedClassVersionError("Class ${it.name} found in ${it.classpathElementURL} " + + "has an unsupported class version of ${it.classfileMajorVersion}") + } } + result.getClassesImplementing(clazz.name) + .filterNot(ClassInfo::isAbstract) + .mapToSet(ClassInfo::getName) } - result.getClassesImplementing(clazz.name) - .filterNot(ClassInfo::isAbstract) - .mapToSet(ClassInfo::getName) - } } /** diff --git a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt index f8d92e6702..070ad4b6ac 100644 --- a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt @@ -1,4 +1,4 @@ -@file:Suppress("TooManyFunctions") +@file:Suppress("MatchingDeclarationName") package net.corda.core.internal import net.corda.core.contracts.ContractClassName @@ -36,24 +36,6 @@ fun checkMinimumPlatformVersion(minimumPlatformVersion: Int, requiredMinPlatform } } -// JDK11: revisit (JDK 9+ uses different numbering scheme: see https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html) -@Throws(NumberFormatException::class) -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") - } -} - /** Checks if this flow is an idempotent flow. */ fun Class>.isIdempotentFlow(): Boolean { return IdempotentFlow::class.java.isAssignableFrom(this) diff --git a/node-api/build.gradle b/node-api/build.gradle index 79e04a203c..30697e4a10 100644 --- a/node-api/build.gradle +++ b/node-api/build.gradle @@ -61,7 +61,6 @@ dependencies { runtimeOnly 'com.mattbertolini:liquibase-slf4j:2.0.0' - // JDK11: required by Quasar at run-time runtimeOnly "com.esotericsoftware:kryo:$kryo_version" testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version" diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/kryo/CordaClosureSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/kryo/CordaClosureSerializer.kt index 13ecd2682c..aed7096a37 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/kryo/CordaClosureSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/kryo/CordaClosureSerializer.kt @@ -19,11 +19,3 @@ object CordaClosureSerializer : ClosureSerializer() { return target is Serializable } } - -object CordaClosureBlacklistSerializer : ClosureSerializer() { - const val ERROR_MESSAGE = "Java 8 Lambda expressions are not supported for serialization." - - override fun write(kryo: Kryo, output: Output, target: Any) { - throw IllegalArgumentException(ERROR_MESSAGE) - } -} \ No newline at end of file diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/kryo/KryoTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/kryo/KryoTests.kt index f58d46312c..f81252c499 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/kryo/KryoTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/kryo/KryoTests.kt @@ -6,8 +6,6 @@ import com.esotericsoftware.kryo.KryoSerializable import com.esotericsoftware.kryo.io.Input import com.esotericsoftware.kryo.io.Output import com.google.common.primitives.Ints -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.whenever import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.SignatureAttachmentConstraint import net.corda.core.crypto.Crypto @@ -37,8 +35,6 @@ import net.corda.serialization.internal.encodingNotPermittedFormat import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.TestIdentity import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule -import org.apache.commons.lang3.JavaVersion -import org.apache.commons.lang3.SystemUtils import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.catchThrowable @@ -50,6 +46,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.junit.runners.Parameterized.Parameters +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.whenever import org.slf4j.LoggerFactory import java.io.InputStream import java.time.Instant @@ -67,7 +65,7 @@ class KryoTests(private val compression: CordaSerializationEncoding?) { private val ALICE_PUBKEY = TestIdentity(ALICE_NAME, 70).publicKey @Parameters(name = "{0}") @JvmStatic - fun compression() = arrayOf(null) + CordaSerializationEncoding.values() + fun compression(): List = CordaSerializationEncoding.entries + null } @get:Rule @@ -399,11 +397,7 @@ class KryoTests(private val compression: CordaSerializationEncoding?) { val obj = Holder(ByteArray(20000)) val uncompressedSize = obj.checkpointSerialize(context.withEncoding(null)).size val compressedSize = obj.checkpointSerialize(context.withEncoding(CordaSerializationEncoding.SNAPPY)).size - // If these need fixing, sounds like Kryo wire format changed and checkpoints might not survive an upgrade. - if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_11)) - assertEquals(20127, uncompressedSize) - else - assertEquals(20234, uncompressedSize) + assertEquals(20127, uncompressedSize) assertEquals(1095, compressedSize) } } diff --git a/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt b/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt index 3cd10809dd..428b0fb324 100644 --- a/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt @@ -3,7 +3,6 @@ package net.corda.node.amqp import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever -import net.corda.core.internal.JavaVersion import net.corda.core.toFuture import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.contextLogger @@ -23,8 +22,8 @@ import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.BOB_NAME import net.corda.testing.driver.internal.incrementalPortAllocation import net.corda.testing.internal.fixedCrlSource -import org.junit.Assume.assumeFalse import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder @@ -43,6 +42,7 @@ import kotlin.test.assertTrue * * In order to have control over handshake internals a simple TLS server is created which may have a configurable handshake delay. */ +@Ignore // These tests were disabled for JDK11+ very shortly after being introduced (https://github.com/corda/corda/pull/6560) @RunWith(Parameterized::class) class AMQPClientSslErrorsTest(@Suppress("unused") private val iteration: Int) { @@ -144,10 +144,7 @@ class AMQPClientSslErrorsTest(@Suppress("unused") private val iteration: Int) { } @Test(timeout = 300_000) - fun trivialClientServerExchange() { - // SSL works quite differently in JDK 11 and re-work is needed - assumeFalse(JavaVersion.isVersionAtLeast(JavaVersion.Java_11)) - + fun `trivial client server exchange`() { val serverPort = portAllocation.nextPort() val serverThread = ServerThread(serverKeyManagerFactory, serverTrustManagerFactory, serverPort).also { it.start() } @@ -182,10 +179,7 @@ class AMQPClientSslErrorsTest(@Suppress("unused") private val iteration: Int) { } @Test(timeout = 300_000) - fun amqpClientServerConnect() { - // SSL works quite differently in JDK 11 and re-work is needed - assumeFalse(JavaVersion.isVersionAtLeast(JavaVersion.Java_11)) - + fun `amqp client server connect`() { val serverPort = portAllocation.nextPort() val serverThread = ServerThread(serverKeyManagerFactory, serverTrustManagerFactory, serverPort) .also { it.start() } @@ -205,10 +199,7 @@ class AMQPClientSslErrorsTest(@Suppress("unused") private val iteration: Int) { } @Test(timeout = 300_000) - fun amqpClientServerHandshakeTimeout() { - // SSL works quite differently in JDK 11 and re-work is needed - assumeFalse(JavaVersion.isVersionAtLeast(JavaVersion.Java_11)) - + fun `amqp client server handshake timeout`() { val serverPort = portAllocation.nextPort() val serverThread = ServerThread(serverKeyManagerFactory, serverTrustManagerFactory, serverPort, 5.seconds) .also { it.start() } 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 8d12f27003..629f21a8aa 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -1155,9 +1155,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration, return NodeVaultService(platformClock, keyManagementService, services, database, schemaService, cordappLoader.appClassLoader) } - // JDK 11: switch to directly instantiating jolokia server (rather than indirectly via dynamically self attaching Java Agents, - // which is no longer supported from JDK 9 onwards (https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8180425). - // No longer need to use https://github.com/electronicarts/ea-agent-loader either (which is also deprecated) private fun initialiseJolokia() { configuration.jmxMonitoringHttpPort?.let { port -> val config = JolokiaServerConfig(mapOf("port" to port.toString())) diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index 60b32a9b10..502be42bf9 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -17,7 +17,6 @@ import net.corda.core.internal.Emoji import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.errors.AddressBindingException -import net.corda.core.internal.getJavaUpdateVersion import net.corda.core.internal.notary.NotaryService import net.corda.core.messaging.RPCOps import net.corda.core.node.NetworkParameters @@ -170,7 +169,7 @@ open class Node(configuration: NodeConfiguration, fun isInvalidJavaVersion(): Boolean { if (!hasMinimumJavaVersion()) { - println("You are using a version of Java that is not supported (${SystemUtils.JAVA_VERSION}). Please upgrade to the latest version of Java 8.") + println("You are using a version of Java that is not supported (${SystemUtils.JAVA_VERSION}). Please upgrade to the latest version of Java 17.") println("Corda will now exit...") return true } @@ -178,17 +177,7 @@ open class Node(configuration: NodeConfiguration, } private fun hasMinimumJavaVersion(): Boolean { - // JDK 11: review naming convention and checking of 'minUpdateVersion' and 'distributionType` (OpenJDK, Oracle, Zulu, AdoptOpenJDK, Cornetto) - return try { - if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_11)) - return true - else { - val update = getJavaUpdateVersion(SystemUtils.JAVA_VERSION) // To filter out cases like 1.8.0_202-ea - (SystemUtils.IS_JAVA_1_8 && update >= 171) - } - } catch (e: NumberFormatException) { // custom JDKs may not have the update version (e.g. 1.8.0-adoptopenjdk) - false - } + return SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_17) } } diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 2bfe9d023b..4ab3520544 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -279,8 +279,6 @@ open class NodeStartup : NodeStartupLogging { logger.info("PID: ${ProcessHandle.current().pid()}") logger.info("Main class: ${NodeConfiguration::class.java.location.toURI().path}") logger.info("CommandLine Args: ${info.inputArguments.joinToString(" ")}") - // JDK 11 (bootclasspath no longer supported from JDK 9) - if (info.isBootClassPathSupported) logger.info("bootclasspath: ${info.bootClassPath}") logger.info("classpath: ${info.classPath}") logger.info("VM ${info.vmName} ${info.vmVendor} ${info.vmVersion}") logger.info("Machine: ${lookupMachineNameAndMaybeWarn()}") diff --git a/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt b/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt index b1e1ceb1f0..14e675349b 100644 --- a/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt +++ b/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt @@ -111,7 +111,7 @@ class NodeSchedulerService(private val clock: CordaClock, } /** - * Convert a Guava [ListenableFuture] or JDK8 [CompletableFuture] to Quasar implementation and set to true when a result + * Convert a Guava [ListenableFuture] or JDK [CompletableFuture] to Quasar implementation and set to true when a result * or [Throwable] is available in the original. * * We need this so that we do not block the actual thread when calling get(), but instead allow a Quasar context diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowCreator.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowCreator.kt index ab0df0ea1e..a9461d643d 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowCreator.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowCreator.kt @@ -213,7 +213,7 @@ class FlowCreator( } private fun verifyFlowLogicIsSuspendable(logic: FlowLogic) { - // Quasar requires (in Java 8) that at least the call method be annotated suspendable. Unfortunately, it's + // Quasar requires that at least the call method be annotated suspendable. Unfortunately, it's // easy to forget to add this when creating a new flow, so we check here to give the user a better error. // // The Kotlin compiler can sometimes generate a synthetic bridge method from a single call declaration, which diff --git a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt index 647b47ee6d..d102e7ddf0 100644 --- a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt @@ -1,7 +1,6 @@ package net.corda.node.internal import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.getJavaUpdateVersion import net.corda.core.internal.readObject import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize @@ -25,7 +24,6 @@ import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.internal.configureDatabase import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import org.assertj.core.api.Assertions.assertThat -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder @@ -38,7 +36,6 @@ import kotlin.io.path.deleteExisting import kotlin.io.path.name import kotlin.io.path.useDirectoryEntries import kotlin.test.assertEquals -import kotlin.test.assertFailsWith import kotlin.test.assertNull class NodeTest { @@ -141,11 +138,11 @@ class NodeTest { serial = nodeInfo1.serial ) - configureDatabase(configuration.dataSourceProperties, configuration.database, { null }, { null }).use { - it.transaction { + configureDatabase(configuration.dataSourceProperties, configuration.database, { null }, { null }).use { persistence -> + persistence.transaction { session.save(persistentNodeInfo1) } - it.transaction { + persistence.transaction { session.save(persistentNodeInfo2) } @@ -160,16 +157,6 @@ class NodeTest { } } - // JDK11: revisit (JDK 9+ uses different numbering scheme: see https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html) - @Ignore - @Test(timeout=300_000) - fun `test getJavaUpdateVersion`() { - assertThat(getJavaUpdateVersion("1.8.0_202-ea")).isEqualTo(202) - assertThat(getJavaUpdateVersion("1.8.0_202")).isEqualTo(202) - assertFailsWith { getJavaUpdateVersion("1.8.0_202wrong-format") } - assertFailsWith { getJavaUpdateVersion("1.8.0-adoptopenjdk") } - } - private fun getAllInfos(database: CordaPersistence): List { return database.transaction { val criteria = session.criteriaBuilder.createQuery(NodeInfoSchemaV1.PersistentNodeInfo::class.java) diff --git a/node/src/test/kotlin/net/corda/node/utilities/ClockUtilsTest.kt b/node/src/test/kotlin/net/corda/node/utilities/ClockUtilsTest.kt index 2a755389b9..e903e03047 100644 --- a/node/src/test/kotlin/net/corda/node/utilities/ClockUtilsTest.kt +++ b/node/src/test/kotlin/net/corda/node/utilities/ClockUtilsTest.kt @@ -1,6 +1,5 @@ package net.corda.node.utilities - import co.paralleluniverse.fibers.FiberExecutorScheduler import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.strands.Strand @@ -12,6 +11,7 @@ import net.corda.node.CordaClock import net.corda.node.SimpleClock import net.corda.node.services.events.NodeSchedulerService import net.corda.testing.node.TestClock +import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.junit.After import org.junit.Before import org.junit.Test @@ -22,13 +22,11 @@ import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import kotlin.test.assertFalse import kotlin.test.assertTrue -import kotlin.test.fail class ClockUtilsTest { - - lateinit var realClock: Clock - lateinit var stoppedClock: CordaClock - lateinit var executor: ExecutorService + private lateinit var realClock: Clock + private lateinit var stoppedClock: CordaClock + private lateinit var executor: ExecutorService @Before fun setup() { @@ -133,53 +131,51 @@ class ClockUtilsTest { val testClock = TestClock(stoppedClock) val advancedClock = Clock.offset(stoppedClock, 10.hours) - try { + assertThatExceptionOfType(InterruptedException::class.java).isThrownBy { NodeSchedulerService.awaitWithDeadline(testClock, advancedClock.instant(), SettableFuture.create()) - fail("Expected InterruptedException") - } catch (exception: InterruptedException) { } } @Test(timeout=300_000) -@Suspendable - fun `test waiting for a deadline with multiple clock advance and incomplete JDK8 future on Fibers`() { + @Suspendable + fun `test waiting for a deadline with multiple clock advance and incomplete JDK future on Fibers`() { val advancedClock = Clock.offset(stoppedClock, 1.hours) val testClock = TestClock(stoppedClock) val future = CompletableFuture() val scheduler = FiberExecutorScheduler("test", executor) - val fiber = scheduler.newFiber(@Suspendable { + val fiber = scheduler.newFiber @Suspendable { future.complete(NodeSchedulerService.awaitWithDeadline(testClock, advancedClock.instant(), future)) - }).start() + }.start() for (advance in 1..6) { - scheduler.newFiber(@Suspendable { + scheduler.newFiber @Suspendable { // Wait until fiber is waiting while (fiber.state != Strand.State.TIMED_WAITING) { Strand.sleep(1) } testClock.advanceBy(10.minutes) - }).start() + }.start() } assertFalse(future.getOrThrow(), "Should have reached deadline") } @Test(timeout=300_000) -@Suspendable + @Suspendable fun `test waiting for a deadline with multiple clock advance and incomplete Guava future on Fibers`() { val advancedClock = Clock.offset(stoppedClock, 1.hours) val testClock = TestClock(stoppedClock) val future = SettableFuture.create() val scheduler = FiberExecutorScheduler("test", executor) - val fiber = scheduler.newFiber(@Suspendable { + val fiber = scheduler.newFiber @Suspendable { future.set(NodeSchedulerService.awaitWithDeadline(testClock, advancedClock.instant(), future)) - }).start() + }.start() for (advance in 1..6) { - scheduler.newFiber(@Suspendable { + scheduler.newFiber @Suspendable { // Wait until fiber is waiting while (fiber.state != Strand.State.TIMED_WAITING) { Strand.sleep(1) } testClock.advanceBy(10.minutes) - }).start() + }.start() } assertFalse(future.getOrThrow(), "Should have reached deadline") } diff --git a/serialization-tests/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt b/serialization-tests/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt index f69276b399..d5a09d413a 100644 --- a/serialization-tests/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt +++ b/serialization-tests/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt @@ -56,6 +56,7 @@ import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.catchThrowable +import org.assertj.core.api.Assumptions.assumeThat import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.cert.X509v2CRLBuilder import org.bouncycastle.cert.jcajce.JcaX509CRLConverter @@ -139,7 +140,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi val MINI_CORP_PUBKEY get() = miniCorp.publicKey @Parameters(name = "{0}") @JvmStatic - fun compression() = arrayOf(null) + CordaSerializationEncoding.values() + fun compression(): List = CordaSerializationEncoding.entries + null } @Rule @@ -534,7 +535,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test(timeout=300_000) fun `class constructor is invoked on deserialisation`() { - compression == null || return // Manipulation of serialized bytes is invalid if they're compressed. + assumeThat(compression).isNull() val serializerFactory = SerializerFactoryBuilder.build(AllWhitelist, ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) ) @@ -641,7 +642,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi private fun assertSerializedThrowableEquivalent(t: Throwable, desThrowable: Throwable) { assertTrue(desThrowable is CordaRuntimeException) // Since we don't handle the other case(s) yet assertEquals("${t.javaClass.name}: ${t.message}", desThrowable.message) - assertTrue(Objects.deepEquals(t.stackTrace.toStackTraceBasic, desThrowable.stackTrace.toStackTraceBasic)) + assertTrue(Objects.deepEquals(t.stackTrace.map(::BasicStrackTraceElement), desThrowable.stackTrace.map(::BasicStrackTraceElement))) assertEquals(t.suppressed.size, desThrowable.suppressed.size) t.suppressed.zip(desThrowable.suppressed).forEach { (before, after) -> assertSerializedThrowableEquivalent(before, after) } } @@ -1582,35 +1583,19 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi assertEquals(1018, compressedSize) } - // JDK11: backwards compatibility function to deal with StacktraceElement comparison pre-JPMS private fun deepEquals(a: Any?, b: Any?): Boolean { - return if (a === b) - true - else if (a == null || b == null) - false - else { - if (a is Exception && b is Exception) - (a.cause == b.cause && a.localizedMessage == b.localizedMessage && a.message == b.message) && - Objects.deepEquals(a.stackTrace.toStackTraceBasic, b.stackTrace.toStackTraceBasic) - else - Objects.deepEquals(a, b) + return when { + a is Throwable && b is Throwable -> BasicThrowable(a) == BasicThrowable(b) + else -> Objects.deepEquals(a, b) } } - private val Array.toStackTraceBasic: Unit - get() { - this.map { StackTraceElementBasic(it as StackTraceElement) } - } + private data class BasicThrowable(val cause: BasicThrowable?, val message: String?, val stackTrace: List) { + constructor(t: Throwable) : this(t.cause?.let(::BasicThrowable), t.message, t.stackTrace.map(::BasicStrackTraceElement)) + } // JPMS adds additional fields that are not equal according to classloader/module hierarchy - data class StackTraceElementBasic(val ste: StackTraceElement) { - override fun equals(other: Any?): Boolean { - return if (other is StackTraceElementBasic) - (ste.className == other.ste.className) && - (ste.methodName == other.ste.methodName) && - (ste.fileName == other.ste.fileName) && - (ste.lineNumber == other.ste.lineNumber) - else false - } + private data class BasicStrackTraceElement(val className: String, val methodName: String, val fileName: String?, val lineNumber: Int) { + constructor(ste: StackTraceElement) : this(ste.className, ste.methodName, ste.fileName, ste.lineNumber) } } diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/ObjectBuilder.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/ObjectBuilder.kt index 7c08c103b0..76f15df55c 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/ObjectBuilder.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/ObjectBuilder.kt @@ -50,17 +50,11 @@ private class SetterCaller(val setter: Method) : (Any, Any?) -> Unit { try { setter.invoke(target, value) } catch (e: InvocationTargetException) { - @Suppress("DEPRECATION") // JDK11: isAccessible() should be replaced with canAccess() (since 9) throw NotSerializableException( - "Setter ${setter.declaringClass}.${setter.name} (isAccessible=${setter.isAccessible} " + - "failed when called with parameter $value: ${e.cause!!.message}" + "Setter ${setter.declaringClass}.${setter.name} failed when called with parameter $value: ${e.cause?.message}" ) } catch (e: IllegalAccessException) { - @Suppress("DEPRECATION") // JDK11: isAccessible() should be replaced with canAccess() (since 9) - throw NotSerializableException( - "Setter ${setter.declaringClass}.${setter.name} (isAccessible=${setter.isAccessible} " + - "not accessible: ${e.message}" - ) + throw NotSerializableException("Setter ${setter.declaringClass}.${setter.name} not accessible: ${e.message}") } } } @@ -206,7 +200,7 @@ private class SetterBasedObjectBuilder( * and calling a constructor with those parameters to obtain the configured object instance. */ private class ConstructorBasedObjectBuilder( - private val constructorInfo: LocalConstructorInformation, + constructorInfo: LocalConstructorInformation, private val slotToCtorArgIdx: IntArray ) : ObjectBuilder { diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt index c8ddc0b0ad..bae489c841 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt @@ -5,24 +5,27 @@ import net.corda.core.identity.Party import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.internal.concurrent.fork import net.corda.core.internal.concurrent.transpose -import net.corda.core.node.NodeInfo import net.corda.core.node.NotaryInfo import net.corda.core.utilities.getOrThrow +import net.corda.coretesting.internal.testThreadFactory import net.corda.node.VersionInfo import net.corda.node.internal.FlowManager import net.corda.node.internal.Node import net.corda.node.internal.NodeFlowManager import net.corda.node.internal.NodeWithInfo -import net.corda.node.services.config.* +import net.corda.node.services.config.ConfigHelper +import net.corda.node.services.config.FlowOverrideConfig +import net.corda.node.services.config.NodeConfiguration +import net.corda.node.services.config.configOf +import net.corda.node.services.config.parseAsNodeConfiguration +import net.corda.node.services.config.plus import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.config.toConfig import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.driver.internal.incrementalPortAllocation -import net.corda.coretesting.internal.testThreadFactory import net.corda.testing.node.User -import org.apache.commons.lang3.SystemUtils import org.apache.logging.log4j.Level import org.junit.After import org.junit.Before @@ -34,7 +37,6 @@ import java.util.concurrent.Executors import kotlin.concurrent.thread import kotlin.io.path.createDirectories import kotlin.io.path.div -import kotlin.test.assertFalse // TODO Some of the logic here duplicates what's in the driver - the reason why it's not straightforward to replace it by // using DriverDSLImpl in `init()` and `stopAllNodes()` is because of the platform version passed to nodes (driver doesn't @@ -161,12 +163,9 @@ class InProcessNode( configuration: NodeConfiguration, versionInfo: VersionInfo, flowManager: FlowManager = NodeFlowManager(configuration.flowOverrides), - allowHibernateToManageAppSchema: Boolean = true) : Node(configuration, versionInfo, false, flowManager = flowManager, allowHibernateToManageAppSchema = allowHibernateToManageAppSchema) { + allowHibernateToManageAppSchema: Boolean = true +) : Node(configuration, versionInfo, false, flowManager = flowManager, allowHibernateToManageAppSchema = allowHibernateToManageAppSchema) { override val runMigrationScripts: Boolean = true - override fun start(): NodeInfo { - assertFalse(isInvalidJavaVersion(), "You are using a version of Java that is not supported (${SystemUtils.JAVA_VERSION}). Please upgrade to the latest version of Java 8.") - return super.start() - } override val rxIoScheduler get() = CachedThreadScheduler(testThreadFactory()).also { runOnStop += it::shutdown } diff --git a/testing/testserver/src/main/kotlin/net/corda/webserver/WebServer.kt b/testing/testserver/src/main/kotlin/net/corda/webserver/WebServer.kt index ab96dc45e2..55ff477283 100644 --- a/testing/testserver/src/main/kotlin/net/corda/webserver/WebServer.kt +++ b/testing/testserver/src/main/kotlin/net/corda/webserver/WebServer.kt @@ -54,8 +54,6 @@ fun main(args: Array) { val info = ManagementFactory.getRuntimeMXBean() log.info("CommandLine Args: ${info.inputArguments.joinToString(" ")}") log.info("Application Args: ${args.joinToString(" ")}") - // JDK 11 (bootclasspath no longer supported from JDK 9) - if (info.isBootClassPathSupported) log.info("bootclasspath: ${info.bootClassPath}") log.info("classpath: ${info.classPath}") log.info("VM ${info.vmName} ${info.vmVendor} ${info.vmVersion}") log.info("Machine: ${InetAddress.getLocalHost().hostName}")