diff --git a/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt b/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt index f19d30b623..a3bd012535 100644 --- a/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt @@ -115,8 +115,10 @@ abstract class AbstractStateReplacementFlow { } } + // Type parameter should ideally be Unit but that prevents Java code from subclassing it (https://youtrack.jetbrains.com/issue/KT-15964). + // We use Void? instead of Unit? as that's what you'd use in Java. abstract class Acceptor(val otherSide: Party, - override val progressTracker: ProgressTracker = tracker()) : FlowLogic() { + override val progressTracker: ProgressTracker = tracker()) : FlowLogic() { companion object { object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal") object APPROVING : ProgressTracker.Step("State replacement approved") @@ -126,7 +128,7 @@ abstract class AbstractStateReplacementFlow { @Suspendable @Throws(StateReplacementException::class) - override fun call() { + override fun call(): Void? { progressTracker.currentStep = VERIFYING val maybeProposal: UntrustworthyData> = receive(otherSide) val stx: SignedTransaction = maybeProposal.unwrap { @@ -135,6 +137,7 @@ abstract class AbstractStateReplacementFlow { it.stx } approve(stx) + return null } @Suspendable diff --git a/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt index d26e07065b..0cea77446d 100644 --- a/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt @@ -85,15 +85,17 @@ object NotaryFlow { * * Additional transaction validation logic can be added when implementing [receiveAndVerifyTx]. */ + // See AbstractStateReplacementFlow.Acceptor for why it's Void? abstract class Service(val otherSide: Party, val timestampChecker: TimestampChecker, - val uniquenessProvider: UniquenessProvider) : FlowLogic() { + val uniquenessProvider: UniquenessProvider) : FlowLogic() { @Suspendable - override fun call() { + override fun call(): Void? { val (id, inputs, timestamp) = receiveAndVerifyTx() validateTimestamp(timestamp) commitInputStates(inputs, id) signAndSendResponse(id) + return null } /** diff --git a/finance/src/test/java/net/corda/flows/AbstractStateReplacementFlowTest.java b/finance/src/test/java/net/corda/flows/AbstractStateReplacementFlowTest.java new file mode 100644 index 0000000000..163388cf3b --- /dev/null +++ b/finance/src/test/java/net/corda/flows/AbstractStateReplacementFlowTest.java @@ -0,0 +1,18 @@ +package net.corda.flows; + +import net.corda.core.crypto.Party; +import net.corda.core.utilities.ProgressTracker; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public class AbstractStateReplacementFlowTest { + + // Acceptor used to have a type parameter of Unit which prevented Java code from subclassing it (https://youtrack.jetbrains.com/issue/KT-15964). + private static class TestAcceptorCanBeInheritedInJava extends AbstractStateReplacementFlow.Acceptor { + public TestAcceptorCanBeInheritedInJava(@NotNull Party otherSide, @NotNull ProgressTracker progressTracker) { + super(otherSide, progressTracker); + } + @Override + protected void verifyProposal(@NotNull AbstractStateReplacementFlow.Proposal proposal) {} + } +} \ No newline at end of file