From 25f335861b1bdcb539c65746548d889c105cf784 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Thu, 2 May 2019 18:03:02 +0100 Subject: [PATCH] Fix ClassNotFound handling (#5078) --- .../net/corda/core/transactions/TransactionBuilder.kt | 11 ++++++++++- .../serialization/internal/amqp/AMQPExceptions.kt | 10 ++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt index 8bd0b475af..fa8de9dfcb 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt @@ -27,6 +27,7 @@ import java.util.regex.Pattern import kotlin.collections.ArrayList import kotlin.collections.component1 import kotlin.collections.component2 +import kotlin.reflect.KClass /** * A TransactionBuilder is a transaction class that's mutable (unlike the others which are all immutable). It is @@ -169,6 +170,13 @@ open class TransactionBuilder( wireTx } + // Returns the first exception in the hierarchy that matches one of the [types]. + private tailrec fun Throwable.rootClassNotFoundCause(vararg types: KClass<*>): Throwable = when { + this::class in types -> this + this.cause == null -> this + else -> this.cause!!.rootClassNotFoundCause(*types) + } + /** * @return true if a new dependency was successfully added. */ @@ -178,7 +186,8 @@ open class TransactionBuilder( // The transaction verified successfully without adding any extra dependency. false } catch (e: Throwable) { - val rootError = e.rootCause + val rootError = e.rootClassNotFoundCause(ClassNotFoundException::class, NoClassDefFoundError::class) + when { // Handle various exceptions that can be thrown during verification and drill down the wrappings. // Note: this is a best effort to preserve backwards compatibility. diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPExceptions.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPExceptions.kt index ea81fb0d69..e4655d8f34 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPExceptions.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPExceptions.kt @@ -23,10 +23,12 @@ internal inline fun ifThrowsAppend(strToAppendFn: () -> String, block: () -> try { return block() } catch (th: Throwable) { - if (th is AMQPNotSerializableException) { - th.classHierarchy.add(strToAppendFn()) - } else { - th.setMessage("${strToAppendFn()} -> ${th.message}") + when (th) { + is AMQPNotSerializableException -> th.classHierarchy.add(strToAppendFn()) + // Do not overwrite the message of these exceptions as it may be used. + is ClassNotFoundException -> {} + is NoClassDefFoundError -> {} + else -> th.setMessage("${strToAppendFn()} -> ${th.message}") } throw th }