java.util.concurrent.RejectedExecutionException when action calls runAsync - javafx

I noticed while updating my TornadoFX version from 1.7.12 to 1.7.14 that one of my tests broke. Things seemed to go off the rails when a runAsyncWithProgress in the View under test was rejected by a ThreadPoolExecutor with status Terminated. I saw in the release notes for 1.7.13 there was a change "internal thread pools are shut down on app exit". Setting the TornadoFX version to 1.7.13 resulted in the same failure, confirming my suspicion that it was related to the above change.
I wrote a simple app to demonstrate this bug.
// src/main/kotlin/me/carltonwhitehead/AsyncBugApp.kt
class AsyncBugApp : App(MainView::class)
/**
* The main method is needed to support the mvn jfx:run goal.
*/
fun main(args: Array<String>) {
Application.launch(AsyncBugApp::class.java, *args)
}
class MainView : View("Async Bug App") {
val controller: MainController by inject()
override val root = pane {
button("Robot-click to repeat bug") {
id = "bug"
action {
runAsync {
controller.onAction("button clicked")
}
}
}
}
}
class MainController : Controller() {
fun onAction(message: String) {
println(message)
}
}
And the test
// src/test/kotlin/me/carltonwhitehead/AsyncBugAppTest.kt
#RunWith(Parameterized::class)
class AsyncBugAppTest(val rounds: Int) {
companion object {
#JvmStatic
#Parameterized.Parameters
fun data() : Collection<Array<Int>> {
return listOf(arrayOf(1), arrayOf(1))
}
}
lateinit var robot: FxRobot
lateinit var app: App
#RelaxedMockK
lateinit var controller: MainController
#Rule #JvmField
val timeout = Timeout(10, TimeUnit.SECONDS)
#Before
fun before() {
MockKAnnotations.init(this)
FxToolkit.registerPrimaryStage()
app = AsyncBugApp()
app.scope.set(controller)
FxToolkit.setupApplication { app }
robot = FxRobot()
println("rounds = $rounds")
}
#After
fun after() {
FxToolkit.cleanupStages()
FxToolkit.cleanupApplication(app)
}
#Test()
fun itShouldSurviveRunAsyncMultipleTimes() {
val latch = CountDownLatch(rounds)
every { controller.onAction(any()) }.answers { latch.countDown() }
var i = 0
while(i <= rounds) {
robot.clickOn("#bug")
i++
}
latch.await()
verify(exactly = rounds) { controller.onAction(any()) }
}
}
The first time that test executes, it passes. The second time, it hangs, because the runAsync is rejected with the below stack trace.
--- Exception in Async Thread ---
java.util.concurrent.RejectedExecutionException: Task tornadofx.FXTask#a315135 rejected from java.util.concurrent.ThreadPoolExecutor#75bde925[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 2]
java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2104)
java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:848)
java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1397)
tornadofx.AsyncKt.task(Async.kt:76)
tornadofx.AsyncKt.task(Async.kt:69)
tornadofx.Component.runAsync(Component.kt:272)
tornadofx.Component.runAsync$default(Component.kt:988)
me.carltonwhitehead.MainView$root$1$1$1.invoke(AsyncBugApp.kt:21)
me.carltonwhitehead.MainView$root$1$1$1.invoke(AsyncBugApp.kt:15)
tornadofx.ControlsKt$action$2.handle(Controls.kt:513)
tornadofx.ControlsKt$action$2.handle(Controls.kt)
javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
javafx.base/javafx.event.Event.fireEvent(Event.java:198)
javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8863)
javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
javafx.base/javafx.event.Event.fireEvent(Event.java:198)
javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876)
javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
java.base/java.security.AccessController.doPrivileged(Native Method)
javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
java.base/java.lang.Thread.run(Thread.java:844)
I suspect I might be doing something wrong with the TestFX/TornadoFX app lifecycle. Each test cycle is creating a new app instance, so I'm confused why the ThreadPoolExecutor would be retained. Any suggestions?
Repo at https://github.com/carltonwhitehead/fx-async-bug-test

Related

How to get signature from Same Counter Party, multiple times in a single flow?

I need to implement the scenario like, there are CentralParty,PartyA,PartyB.
CentralParty needs to initiate a flow where there will be 3 transactions in a loop ,where inititor is always Central party and the otherparty will be Party A 2 times.
i.e.I m trying to collecting signature from same counterparty with multiple times from a single flow by referring the below link
Corda returning Multiple transactions in a single flow call ()
val flowSessionMap = mutableMapOf<Party, FlowSession>()
var ftx:MutableList<SignedTransaction> = mutableListOf<SignedTransaction>()
var signedTransaction:SignedTransaction
val fullySignedTransactions = matchingStateList.forEach { matchingState ->
val txCommand = Command(IOUContract.Commands.Matching(), matchingState.participants.map { it.owningKey })
val txBuilder = TransactionBuilder(notary)
.addOutputState(matchingState, IOU_CONTRACT_ID)
.addCommand(txCommand)
// Stage 2.
progressTracker.currentStep = VERIFYING_TRANSACTION
// Verify that the transaction is valid.
txBuilder.verify(serviceHub)
// Stage 3.
progressTracker.currentStep = SIGNING_TRANSACTION
// Sign the transaction.
val partSignedTx = serviceHub.signInitialTransaction(txBuilder, ourIdentity.owningKey)
val sessions = (listOf(PartyA).map { signer ->
flowSessionMap.getOrPut(signer) {
initiateFlow(signer)
}
})
val fullySignedTransaction = subFlow(CollectSignaturesInitiatingFlow(
partSignedTx, sessions)
)
signedTransaction = fullySignedTransaction
ftx.add(signedTransaction)
}
for (transaction in ftx) {
subFlow(FinalityFlow(transaction))
}
Responder flow is defined as follows:
class Acceptor(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
#Suspendable
override fun call(): SignedTransaction {
val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
override fun checkTransaction(stx: SignedTransaction) = requireThat {
val output = stx.tx.outputs.single().data
"This must be an Matching State transaction." using (output is MatchingState)
val Match = output as MatchingState
"I won't accept IOUs with a value over 100." using (iou.value <= 100)
}
}
return subFlow(signTransactionFlow)
}
}
Where CollectSignaturesInitiatingFlow is defined as follows:
#InitiatingFlow
class CollectSignaturesInitiatingFlow(val signedTransaction: SignedTransaction, val sessions: List<FlowSession>): FlowLogic<SignedTransaction>() {
override fun call(): SignedTransaction {
return subFlow(CollectSignaturesFlow(signedTransaction, sessions))
}
}
And the responder for CollectSignaturesInitiatingFlow is defined as follows:
#InitiatedBy(CollectSignaturesInitiatingFlow::class)
class CollectSignaturesInitiatingFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
#Suspendable
override fun call(): SignedTransaction {
val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
override fun checkTransaction(stx: SignedTransaction) {
TODO("Check the transaction here.")
}
}
return subFlow(signTransactionFlow)
}
}
While running the same code I got an error like
[WARN ] 15:43:18,817 [Node thread-1] (FlowStateMachineImpl.kt:111) flow.[82900238-9223-4ace-ba78-9ecc45121b11].run - Terminated by unexpected exception {}
net.corda.core.flows.UnexpectedFlowEndException: Counterparty flow on O=PartyA, L=London, C=GB has completed without sending data
at net.corda.node.services.statemachine.FlowStateMachineImpl.confirmNoError(FlowStateMachineImpl.kt:488) ~[corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.waitForMessage(FlowStateMachineImpl.kt:444) ~[corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.sendAndReceiveInternal(FlowStateMachineImpl.kt:385) ~[corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.sendAndReceive(FlowStateMachineImpl.kt:203) ~[corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.sendAndReceive(FlowSessionImpl.kt:29) ~[corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.sendAndReceive(FlowSessionImpl.kt:40) ~[corda-node-3.2-corda.jar:?]
at net.corda.core.flows.DataVendingFlow.sendPayloadAndReceiveDataRequest(SendTransactionFlow.kt:70) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.DataVendingFlow.call(SendTransactionFlow.kt:48) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.DataVendingFlow.call(SendTransactionFlow.kt:31) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.CollectSignatureFlow.call(CollectSignaturesFlow.kt:142) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.CollectSignatureFlow.call(CollectSignaturesFlow.kt:135) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:114) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:64) ~[corda-core-3.2-corda.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2-corda.jar:?]
at com.example.flow.ExampleFlowMatching$CollectSignaturesInitiatingFlow.call(ExampleFlowMatching.kt:260) ~[classes/:?]
at com.example.flow.ExampleFlowMatching$CollectSignaturesInitiatingFlow.call(ExampleFlowMatching.kt:258) ~[classes/:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2-corda.jar:?]
at com.example.flow.ExampleFlowMatching$ExampleFlowMatchingInitiator.call(ExampleFlowMatching.kt:202) ~[classes/:?]
at com.example.flow.ExampleFlowMatching$ExampleFlowMatchingInitiator.call(ExampleFlowMatching.kt:45) ~[classes/:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96) [corda-node-3.2-corda.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44) [corda-node-3.2-corda.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_191]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_191]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_191]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:62) [corda-node-3.2-corda.jar:?]
The issue is that you are initiating the flow sessions in your main flow, ExampleFlowMatchingInitiator, instead of inside CollectSignaturesInitiatingFlow.
When you call initiateFlow, it starts a flow session with the counterparty in the context of the current InitiatingFlow. So when you call initiateFlow in ExampleFlowMatchingInitiator, the counterparty will check whether it has any responders registered for ExampleFlowMatchingInitiator. It does - Acceptor - so it starts a flow session to speak to the counterparty using Acceptor.
If you call initiateFlow inside CollectSignaturesInitiatingFlow instead, the counterparty will check whether it has any responders registered for CollectSignaturesInitiatingFlow. It does - CollectSignaturesInitiatingFlowResponder - so it starts a flow session to speak to the counterparty using CollectSignaturesInitiatingFlowResponder instead.

Implementing FungibleAsset

I have some troubles implementing a FungibleAsset contract.
The Dapp should consist of a Pool which is tokenized through PoolToken. For the PoolToken I implement the FungibleAsset class. There is a flow called CreatePoolFlow which uses the Create-Command from the Pool and the Issue-Command from the PoolToken. This flow should create a new Pool and Issue a specified number of Tokens the the Creator. When invoking the Flow an Error occurs.
Is there any guide on how to implement FungibleAsset or in general Tokens?
Thanks in advance for any help!
Pool.kt:
package com.company
//imports here
// *****************
// * Contract Code *
// *****************
class Pool : Contract {
// This is used to identify our contract when building a transaction
companion object {
const val POOL_CONTRACT_ID: ContractClassName = "com.company.Pool"
}
// A transaction is considered valid if the verify() function of the contract of each of the transaction's input
// and output states does not throw an exception.
override fun verify(tx: LedgerTransaction) {
//requireSingleCommand
var command = tx.commands.requireSingleCommand<Pool.Commands>()
val timeWindow: TimeWindow? = tx.timeWindow
when (command.value) {
is Commands.Create -> {
}
else -> throw IllegalArgumentException("Unrecognised command!")
}
}
// Used to indicate the transaction's intent.
interface Commands : CommandData {
class Create : TypeOnlyCommandData(), Commands
}
}
// *********
// * State *
// *********
data class PoolState(val issuer: Party,
override val participants: List<Party> = listOf(issuer),
val id: UniqueIdentifier = UniqueIdentifier())
//val id: UniqueIdentifier = UniqueIdentifier()) //val loans: Array<StateRef<Loan>>
: ContractState {
//override val participants = listOf(issuer)
//fun withoutOwner() = copy(issuer = AnonymousParty(NullKeys.NullPublicKey))
}
PoolToken.kt:
package com.company
//imports here
// *****************
// * Contract Code *
// *****************
class PoolToken : Contract {
// This is used to identify our contract when building a transaction
companion object {
const val POOLTOKEN_CONTRACT_ID: ContractClassName = "com.company.PoolToken"
}
// A transaction is considered valid if the verify() function of the contract of each of the transaction's input
// and output states does not throw an exception.
override fun verify(tx: LedgerTransaction) {
//requireSingleCommand
var command = tx.commands.requireSingleCommand<PoolToken.Commands>()
val timeWindow: TimeWindow? = tx.timeWindow
when (command.value) {
is Commands.Issue -> {
}
is Commands.Move -> {
}
is Commands.Exit -> {
}
else -> throw IllegalArgumentException("Unrecognised command!")
}
}
// Used to indicate the transaction's intent.
interface Commands : CommandData {
class Move : TypeOnlyCommandData(), Commands
class Issue : TypeOnlyCommandData(), Commands
class Exit : TypeOnlyCommandData(), Commands
}
}
// *********
// * State *
// *********
data class PoolTokenState(override val owner: AbstractParty,
override val amount: Amount<Issued<UniqueIdentifier>>)
: FungibleAsset<UniqueIdentifier> { //TODO: Change to BigDecimal
override val exitKeys = setOf(owner.owningKey) //, amount.token.issuer.party.owningKey
override val participants = listOf(owner)
override fun withNewOwnerAndAmount(newAmount: Amount<Issued<UniqueIdentifier>>, newOwner: AbstractParty): FungibleAsset<UniqueIdentifier>
= copy(amount = amount.copy(newAmount.quantity), owner = newOwner)
//override fun toString() = "$amount Tokens of Pool ${amount.token.product} from ${amount.token.issuer} owned by $owner"
override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(PoolToken.Commands.Move(), copy(owner = newOwner))
//fun withoutOwner() = copy(issuer = AnonymousParty(NullKeys.NullPublicKey))
}
PoolFlows.kt:
package com.company
//imports here
#InitiatingFlow
#StartableByRPC
class CreatePoolFlow(val tokens: Long) : FlowLogic<SignedTransaction>() { //val auditor: Party
override val progressTracker = ProgressTracker()
#Suspendable
override fun call(): SignedTransaction {
//retrieve the notary identity from the network map
val notary = serviceHub.networkMapCache.notaryIdentities.first()
//create a transaction builder
val txBuilder = TransactionBuilder(notary = notary)
//get all parties in the network
//TODO: Construct as set and convert to list in order to prevent duplicates?
val nodes = serviceHub.networkMapCache.allNodes
val _parties = mutableListOf<Party>()
for (node in nodes) {
for (party in node.legalIdentities) {
_parties.add(party)
}
}
val parties: List<Party> = _parties
//create the Pool transaction components
val outputStatePool = PoolState(ourIdentity,parties)
val outputContractAndStatePool = StateAndContract(outputStatePool, POOL_CONTRACT_ID)
val cmdPool = Command(Pool.Commands.Create(), ourIdentity.owningKey)
//create the PoolToken transaction components
val outputStatePoolToken = PoolTokenState(ourIdentity, Amount(tokens,Issued(ourIdentity.ref(),outputStatePool.id)))
val outputContractAndStatePoolToken = StateAndContract(outputStatePoolToken, POOLTOKEN_CONTRACT_ID)
val cmdPoolToken = Command(PoolToken.Commands.Issue(), ourIdentity.owningKey)
//add the items to the builder
txBuilder.withItems(outputContractAndStatePool, cmdPool, outputContractAndStatePoolToken, cmdPoolToken)
//add time
val currentTime = serviceHub.clock.instant()
txBuilder.setTimeWindow(currentTime, 60.seconds)
//verifying the transaction
txBuilder.verify(serviceHub)
//signing the transaction
val signedTx = serviceHub.signInitialTransaction(txBuilder)
// Finalising the transaction.
subFlow(FinalityFlow(signedTx))
return signedTx
}
}
Error when executing the flow:
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Failed requirement.
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at com.company.FlowTests.create pool and tokens(FlowTests.kt:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalArgumentException: Failed requirement.
at net.corda.core.utilities.OpaqueBytes.<init>(ByteArrays.kt:154)
at net.corda.core.utilities.OpaqueBytes$Companion.of(ByteArrays.kt:150)
at net.corda.core.identity.AbstractParty.ref(AbstractParty.kt:32)
at com.company.CreatePoolFlow.call(PoolFlows.kt:63)
at com.company.CreatePoolFlow.call(PoolFlows.kt:34)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44)
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:62)
I assume the problem is in the line
val outputStatePoolToken = PoolTokenState(ourIdentity, Amount(tokens,Issued(ourIdentity.ref(),outputStatePool.id)))
You are creating ourIdenity.ref() with empty bytes, which will cause the exact error.
Pass something like OpaqueBytes.of(0) to it and see if it helps

Corda V1 unit Test code issue

Please any suggest, but I aslo git the core project. most of junit test that have compile errror and some of the can't be run ok. I used below code make Junit test in V14 version the code it's ok. but in CordaV1 version. pop up error as blew:
net.corda.core.transactions.MissingContractAttachments: Cannot find contract attachments for [com.legalcontract.contract.LegalContractCode]
at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core_main(TransactionBuilder.kt:96) ~[corda-core-1.0.0.jar:?]
at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core_main$default(TransactionBuilder.kt:87) ~[corda-core-1.0.0.jar:?]
at net.corda.core.transactions.TransactionBuilder.toWireTransaction(TransactionBuilder.kt:85) ~[corda-core-1.0.0.jar:?]
at net.corda.core.transactions.TransactionBuilder.toLedgerTransaction(TransactionBuilder.kt:107) ~[corda-core-1.0.0.jar:?]
at net.corda.core.transactions.TransactionBuilder.verify(TransactionBuilder.kt:113) ~[corda-core-1.0.0.jar:?]
at com.legalcontract.flow.LegalContractFlow$Initiator.call(LegalContractFlow.kt:247) ~[main/:?]
at com.legalcontract.flow.LegalContractFlow$Initiator.call(LegalContractFlow.kt:47) ~[main/:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:112) [corda-node-1.0.0.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:40) [corda-node-1.0.0.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
Code:
#After
fun tearDown() {
net.stopNodes()
}
#Before
fun setup() {
net = MockNetwork(false, true)
}
class WrapperStream(input: InputStream) : FilterInputStream(input)
#Test
fun `flow a new status valid Legal Contract`() {
val notaryNode = net.createNotaryNode()
val a = net.createPartyNode(notaryNode.network.myAddress, CordaX500Name("a","London","GB"))
val b = net.createPartyNode(notaryNode.network.myAddress, CordaX500Name("b","New York","US"))
a.internals.registerInitiatedFlow(LegalContractFlow.Acceptor::class.java)
b.internals.registerInitiatedFlow(LegalContractFlow.Acceptor::class.java)
val attachment = gInputStreamAndHash()
println(attachment)
val id = a.database.transaction {
a.attachments.importAttachment(attachment.inputStream)
}
assertEquals(attachment.sha256, id, "Attachment has correct SHA256 hash")
LegalContractFlowTests.attachList.add(id.toString())
var fileName: String = "test1"
var legalContract: LegalContract = LegalContract(a.info.legalIdentities.first().name.toString(),LegalContractFlowTests.attachList.get(0))
//
System.out.print(legalContract)
var state: LegalContractState = LegalContractState(
legalContract,
a.info.legalIdentities.first(),
b.info.legalIdentities.first())
val flow = LegalContractFlow.Initiator(state, b.info.chooseIdentity(), false)
val future = a.services.startFlow(flow).resultFuture
var signedTx = future.getOrThrow()
for (node in listOf(a, b)) {
assertEquals(signedTx, node.services.validatedTransactions.getTransaction(signedTx.id))
}
}
In Corda V1, you need to tell your tests which packages to scan when looking for contract attachments - see https://docs.corda.net/key-concepts-contract-constraints.html#testing.
This is a temporary piece of boilerplate only, and is expected to be removed in the future. It is also not required for actual nodes, only for mock nodes.

I can't figure out my error

I have a JavaFX application which have a scheduledExecutorService who's requesting some datas from a server. these datas are used to fill a ListView and when I click on an element in this list a request for more datas is sent to the server and a MQTT connection is set, but a few seconds later I get a NullPointerException from somwhere I don't understand and I don't even know what object points to Null.
Here is the part where the error comes from :
public class DevicePane extends BorderPane {
private final TcpConnection tcp;
private final MqttConnection mqtt;
private final DeviceListView deviceListView;
private SpecificDevicePane deviceInfoPane;
private String[] topicsArray;
public DevicePane() {
tcp = new TcpConnection();
mqtt = new MqttConnection();
mqtt.connect();
deviceListView = new DeviceListView();
deviceListView.getSelectionModel().selectedIndexProperty().addListener(e -> {
if (topicsArray != null) mqtt.unsubscribeToAll(topicsArray);
AnswerMessage answer = tcp.sendRequest(new RequestMessage(RQST_DEVICE_INFO, deviceListView.getSelectionModel().getSelectedItem().toString()));
topicsArray = new String[answer.getParams().size()];
topicsArray = answer.getParams().toArray(topicsArray);
mqtt.subscribeToAll(topicsArray);
deviceInfoPane = new SpecificDevicePane(answer.getParams(), mqtt, tcp);
ScrollPane scrollPane = new ScrollPane(deviceInfoPane);
this.setCenter(scrollPane);
});
this.setLeft(deviceListView);
// Tâche planifiée afin de récupérer la liste des objets IOT de la DB.
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
threadPool.scheduleAtFixedRate(() -> {
refreshDeviceList();
}, 0, 5, TimeUnit.SECONDS);
}
And here is the error I get :
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at view.DevicePane.lambda$new$8(DevicePane.java:36)
at view.DevicePane$$Lambda$77/576256602.invalidated(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.MultipleSelectionModelBase.clearSelection(MultipleSelectionModelBase.java:665)
at javafx.scene.control.ListView$ListViewBitSetSelectionModel.updateSelection(ListView.java:1306)
at javafx.scene.control.ListView$ListViewBitSetSelectionModel.access$1600(ListView.java:1173)
at javafx.scene.control.ListView$ListViewBitSetSelectionModel$1.onChanged(ListView.java:1246)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
at view.DeviceListView.refreshShownDevice(DeviceListView.java:43)
at view.DeviceListView.setDeviceList(DeviceListView.java:33)
at view.DeviceListView.lambda$setDeviceList$7(DeviceListView.java:36)
at view.DeviceListView$$Lambda$160/2054192134.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1826358374.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1915503092.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/1963387170.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Line 36 is this line : AnswerMessage answer = tcp.sendRequest(new RequestMessage(RQST_DEVICE_INFO, deviceListView.getSelectionModel().getSelectedItem().toString()));
I hope someone will be able to help me

Error when using cql3 with Astyanax

I was trying to run a simple Cql3 query with Astyanax and I keep on getting an error.
The aim is to create a simple table via Astyanax using cql3.
public class SomeTest {
private AstyanaxContext<Keyspace> astyanaxContext;
private Keyspace keyspace;
private static String CREATE_TABLE_QUERY = "CREATE TABLE top_items (\n" +
" categoryName varchar,\n" +
" type varchar,\n" +
" baseItemId int,\n" +
" margin float,\n" +
" ds timestamp,\n" +
" PRIMARY KEY (categoryName, ds)\n" +
");";
#Before
public void setUp() {
try {
this.astyanaxContext = new AstyanaxContext.Builder()
.forCluster("ClusterName")
.forKeyspace("new_examples")
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl().setDiscoveryType(NodeDiscoveryType.NONE).setCqlVersion("3.0.0"))
.withConnectionPoolConfiguration(
new ConnectionPoolConfigurationImpl("MyConnectionPool").setMaxConnsPerHost(1).setPort(9160)
.setSeeds("localhost:9160")).withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
this.astyanaxContext.start();
this.keyspace = this.astyanaxContext.getEntity();
// Using simple strategy
keyspace.createKeyspace(ImmutableMap.<String, Object>builder()
.put("strategy_options", ImmutableMap.<String, Object>builder()
.put("replication_factor", "1")
.build())
.put("strategy_class", "SimpleStrategy")
.build()
);
// test the connection
this.keyspace.describeKeyspace();
} catch (Throwable e) {
throw new RuntimeException("Failed to prepare CassandraBolt", e);
}
}
#Test
public void testWrite() throws ConnectionException {
ColumnFamily<String, String> CQL3_CF = ColumnFamily.newColumnFamily(
"Cql3CF",
StringSerializer.get(),
StringSerializer.get());
OperationResult<CqlResult<String, String>> result;
result = keyspace
.prepareQuery(CQL3_CF)
.withCql(CREATE_TABLE_QUERY)
.execute();
}
}
When I run the test I get this stack trace
java.lang.NoSuchMethodError: org.apache.thrift.meta_data.FieldValueMetaData.<init>(BZ)V
at org.apache.cassandra.thrift.Cassandra$execute_cql_query_args.<clinit>(Cassandra.java:32588)
at org.apache.cassandra.thrift.Cassandra$Client.send_execute_cql_query(Cassandra.java:1393)
at org.apache.cassandra.thrift.Cassandra$Client.execute_cql_query(Cassandra.java:1387)
at com.netflix.astyanax.thrift.ThriftColumnFamilyQueryImpl$6$1.internalExecute(ThriftColumnFamilyQueryImpl.java:699)
at com.netflix.astyanax.thrift.ThriftColumnFamilyQueryImpl$6$1.internalExecute(ThriftColumnFamilyQueryImpl.java:696)
at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:55)
at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:27)
at com.netflix.astyanax.thrift.ThriftSyncConnectionFactoryImpl$1.execute(ThriftSyncConnectionFactoryImpl.java:136)
at com.netflix.astyanax.connectionpool.impl.AbstractExecuteWithFailoverImpl.tryOperation(AbstractExecuteWithFailoverImpl.java:69)
at com.netflix.astyanax.connectionpool.impl.AbstractHostPartitionConnectionPool.executeWithFailover(AbstractHostPartitionConnectionPool.java:248)
at com.netflix.astyanax.thrift.ThriftColumnFamilyQueryImpl$6.execute(ThriftColumnFamilyQueryImpl.java:694)
at storage.cassandra.daos.SomeTest.testWrite(SomeTest.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
I'm using "com.netflix.astyanax" % "astyanax" % "1.56.18" .
Please help.
It looks like Astyanax is not properly supporting Cassandra 1.2 or 1.2.1 (not even 1.56.24, released 7 days ago...). You may try java-driver instead. It is not yet released but it works fine, as far as I have tested.
https://github.com/datastax/java-driver

Resources