InvocationHandler in Kotlin - kotlin

I'm reading Head First: Design Patterns (2nd ed) and I followed the code sample but instead of using Java, I used Kotlin. Currently, I'm in a chapter tackling about proxy protection pattern and having difficulty to run it with Kotlin. Please see the code and exceptions below.
Sample code
interface Person {
fun getName(): String
fun setName(name: String)
}
class PersonImpl : Person {
private var _name: String = ""
override fun getName(): String = _name
override fun setName(name: String) {
_name = name
}
}
class OwnerInvocationHandler(private val person: Person) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method, args: Array<Any>?): Any? {
try {
val methodName = method.name
if (methodName.isNullOrEmpty())
return null
if (methodName.startsWith("get")) {
// return method.invoke(proxy, *(args ?: arrayOfNulls<Any>(0))) // << Encountered "EXCEPTION B" below
// return method.invoke(proxy, *(args ?: emptyArray())) // << Encountered "EXCEPTION B" below
// return method.invoke(proxy, *args.orEmpty()) // << Encountered "EXCEPTION B" below
return method.invoke(proxy, args) // << From the code sample, encountered "EXCEPTION A" below
} else if (methodName.startsWith("set")) {
return method.invoke(person, args)
}
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
return null
}
}
// main.kt
val listOfPeople = arrayListOf<Person>()
fun main(array: Array<String>) {
initializeDatabase()
val joe = getPersonFromDatabase("Joe Javabean") ?: return
val ownerProxy = getOwnerProxy(joe)
println("Name is ${ownerProxy.getName()}")
}
fun initializeDatabase() {
val p1 = PersonImpl()
p1.setName("Joe Javabean")
listOfPeople.add(p1)
}
fun getOwnerProxy(person: Person): Person {
return Proxy.newProxyInstance(
person.javaClass.classLoader,
person.javaClass.interfaces,
OwnerInvocationHandler(person)
) as Person
}
fun getPersonFromDatabase(name: String): Person? {
return listOfPeople.firstOrNull { p -> name.contentEquals(p.getName()) }
}
Exception
Exception A
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10a5ef4e0). One of the two will be used. Which one is undefined.
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
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 com.helloworld.app.OwnerInvocationHandler.invoke(OwnerInvocationHandler.kt:17)
at com.sun.proxy.$Proxy0.getName(Unknown Source)
at com.helloworld.app.MainKt.main(main.kt:12)
Exception B
objc[64094]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java (0x109e744c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x109eee4e0). One of the two will be used. Which one is undefined.
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
java.lang.reflect.InvocationTargetExceptionjava.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.helloworld.app.OwnerInvocationHandler.invoke(OwnerInvocationHandler.kt:17)
at com.sun.proxy.$Proxy0.getName(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.helloworld.app.OwnerInvocationHandler.invoke(OwnerInvocationHandler.kt:17)
at com.sun.proxy.$Proxy0.getName(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.helloworld.app.OwnerInvocationHandler.invoke(OwnerInvocationHandler.kt:17)
at com.sun.proxy.$Proxy0.getName(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.helloworld.app.OwnerInvocationHandler.invoke(OwnerInvocationHandler.kt:17)
at com.sun.proxy.$Proxy0.getName(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
...
I found the link below but didn't solve my issue.
Kotlin: Argument Type Mismatch when passing Array as vararg parameter

This is just a user error (embarrassing). As #broot pointed out:
Code Sample
class OwnerInvocationHandler(private val person: Person) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method, args: Array<Any>?): Any? {
try {
val methodName = method.name
if (methodName.isNullOrEmpty())
return null
if (methodName.startsWith("get")) {
// return method.invoke(proxy, *(args ?: arrayOfNulls<Any>(0))) // << Encountered "EXCEPTION B" below
// return method.invoke(proxy, *(args ?: emptyArray())) // << Encountered "EXCEPTION B" below
// return method.invoke(proxy, *args.orEmpty()) // << Encountered "EXCEPTION B" below
// return method.invoke(proxy, args) // << From the code sample, encountered "EXCEPTION A" below
// `person` should be used not `proxy`
return method.invoke(person, *args.orEmpty())
} else if (methodName.startsWith("set")) {
return method.invoke(person, args)
}
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
return null
}
}

Related

Getting java.net.SocketException: No buffer space available and BindException using Jsoup while connecting to url using Kotlin Coroutines

I was trying to do parser for a website, and because there's a lot of content, I used Kotlin coroutines to make parsing asynchronous, but I've ran into a problem where I constantly get java.net.SocketException: No buffer space available (maximum connections reached?): connect at java.base/sun.nio.ch.Net.connect0(Native Method) ~[na:na] at java.base/sun.nio.ch.Net.connect(Net.java:579) ~[na:na] at java.base/sun.nio.ch.Net.connect(Net.java:568) ~[na:na] and Suppressed: java.net.BindException: Address already in use: no further information at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
I use the function below to get a document
fun connect(url: String): Document {
return try {
Jsoup.connect(url).newRequest().get()
} catch (_: SocketTimeoutException) {
println("RETRYING $url")
connect(url)
}
}
and
runBlocking {
withContext(Dispatchers.IO) {
val updated: ArrayList<Deferred<List<Book>>> = arrayListOf()
for (booklist in booklists) {
updated.add(async {
booklist.forEach { book -> book.sections = ru.parseBook(book) }
return#async booklist
})
}
updated.awaitAll().forEach { u -> bookRepository.saveAll(u) }
}
}
to run parser
Worked it out via HttpClient which is being created for every Coroutine:
for (bookList in chunked) {
updated.add(async {
val client = HttpClient.newHttpClient()
bookList.forEach { book -> book.sections = engine.parseBook(book, client) }
return#async bookList
})
}
and passed as a variable into a function
val request = HttpRequest.newBuilder(URI(url)).GET().build()
withContext(Dispatchers.IO) {
val send = httpClient.send(request, HttpResponse.BodyHandlers.ofString())
val doc = Jsoup.parse(send.body())
}

How to solver error for kotlin coroutines flow?

I tried to use NetworkBoundResource for my MVVM Model and after i follow some tutorial, i'm having an error look this
10-21 14:15:04.073 31376-31376/com.example.mvvmsecondmodel E/Process: android_os_Process_getProcessNameByPid pid is 31376
10-21 14:15:04.074 31376-31376/com.example.mvvmsecondmodel E/Process: android_os_Process_getProcessNameByPid value is mvvmsecondmodel
10-21 14:15:04.416 31376-31421/com.example.mvvmsecondmodel E/SQLiteLog: (283) recovered 8 frames from WAL file /data/data/com.example.mvvmsecondmodel/databases/movie_db-wal
10-21 14:15:04.640 31376-31376/com.example.mvvmsecondmodel E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mvvmsecondmodel, PID: 31376
java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.flow.Flow<com.example.mvvmsecondmodel.data.respository.ApiResponse<com.example.mvvmsecondmodel.data.model.MovieResponse$Movie>>
for method ApiService.getMyMovie
at retrofit2.Utils.methodError(Utils.java:52)
at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:105)
at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:66)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:37)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy0.getMyMovie(Unknown Source)
at com.example.mvvmsecondmodel.data.remote.ApiService$DefaultImpls.getMyMovie$default(ApiService.kt:11)
at com.example.mvvmsecondmodel.data.respository.MovieRespository$getListMovie$$inlined$networkBoundResource$1.invokeSuspend(NetworkBoundResource.kt:49)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:55)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for kotlinx.coroutines.flow.Flow<com.example.mvvmsecondmodel.data.respository.ApiResponse<com.example.mvvmsecondmodel.data.model.MovieResponse$Movie>>.
Tried:
* retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
* retrofit2.DefaultCallAdapterFactory
at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241)
at retrofit2.Retrofit.callAdapter(Retrofit.java:205)
at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:103)
... 14 more
At first i thought there's red sign at my code so i checked ApiService and Respository class and nothing wrong cause i already follow the tutorial
ApiService:
interface ApiService {
#GET("3/movie/popular")
fun getMyMovie(#Query("api_key") api : String = "32bbbffe944d16d1d2a3ee46cfc6aaa0"
) : Flow<ApiResponse<MovieResponse.Movie>>
}
MovieRespository:
class MovieRespository (val apiService: ApiService, val movieDao: MovieDao) {
fun getListMovie() : Flow<Resource<Movie>> {
return networkBoundResource(
fetchFromLocal = { movieDao.getMyMovie() },
shouldFetchFromRemote = {true},
fetchFromRemote = {apiService.getMyMovie()},
processRemoteResponse = {},
saveRemoteData = {movieDao.insert(
it.results.let {
it.map { data -> Movie.from(data) }
}
)},
onFetchFailed = {_, _ ->}
).flowOn(Dispatchers.IO)
}
You should define your api service as suspend function.
Api Service:
interface ApiService {
#GET("3/movie/popular")
suspend fun getMyMovie(#Query("api_key") api : String = "32bbbffe944d16d1d2a3ee46cfc6aaa0"
) : ApiResponse<MovieResponse.Movie>
}
Movie Repository:
class MovieRepository (val apiService: ApiService, val movieDao: MovieDao) {
fun getListMovie() : Flow<Resource<Movie>> {
return flow {
// do your networkBoundResource functions
}.flowOn(Dispatchers.IO)
}
I can't test the code because you didn't share your NetworkBoundResource class. I hope the code help to fix your problem.

Corda persistence: unknown entity: PersistentFungibleToken

General description
Good day!
I'm experimenting with corda version 4.3 token SDK version 1.1 and want to try various scenarios with issuance/redeeming custom Fungible tokens.
I wrote a simple flow which describes token issuance for party to itself:
While the very basic flow seems to be working fine, in breaks on the subFlow(IssueTokensFlow), on an attempt to save an PersistentFungibleToken to the database (stack trace below).
I tried to implement my own schema, but with no success, as function supportedScema() requires only List.
I also tried to Issue some tokens without using customized FungilbeToken, with no success either.
How to fix this?
Flow
import co.paralleluniverse.fibers.Suspendable
import com.maker.loyalty.states.NativeToken
import com.maker.loyalty.states.ParticipantNativeFungibleToken
import com.r3.corda.lib.tokens.contracts.states.FungibleToken
import com.r3.corda.lib.tokens.contracts.utilities.heldBy
import com.r3.corda.lib.tokens.contracts.utilities.of
import com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow
import com.r3.corda.lib.tokens.workflows.utilities.getPreferredNotary
import net.corda.core.flows.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker
object IssueTokenExperiment {
private fun tracker() = ProgressTracker(
NotaryInfo,
CreateTransaction,
Verify,
Finalize,
ExchangeValuesSingleParty.ExecuteExchange,
SigningByOtherParty
)
private const val defaultAmount: Long = 2
private val otherPartyDefaultName = CordaX500Name(organisation = "PartyA", locality = "London", country = "GB")
//Scenario - issue token onto the ledger, verify it was issued
#InitiatingFlow
#StartableByRPC
/**
* Issues token to self an notifies the counter party about issuance
* */
class IssueNativeTokenToSelfInitializer(private val amount: Long = defaultAmount,
private val otherPartyX500Name: CordaX500Name = otherPartyDefaultName) : FlowLogic<SignedTransaction>() {
override val progressTracker: ProgressTracker = tracker()
#Suspendable
override fun call(): SignedTransaction {
progressTracker.currentStep = NotaryInfo
getPreferredNotary(serviceHub)
val otherParty: Party = run {
serviceHub.networkMapCache.getPeerByLegalName(otherPartyX500Name)
?: throw FlowException("Other party not found")
}
val otherPartySession = initiateFlow(otherParty)
progressTracker.currentStep = CreateTransaction
val issuedSupplyAmount = NativeToken issuedBy ourIdentity
val supplyAmount = amount of issuedSupplyAmount
// val liability = supplyAmount heldBy ourIdentity
val participantNativeAccountState = ParticipantNativeFungibleToken(
amount = supplyAmount,
issuer = ourIdentity,
participants = listOf(ourIdentity, otherParty),
observers = emptyList(),
owner = ourIdentity
)
return subFlow(IssueTokensFlow(
token = participantNativeAccountState as FungibleToken,
participantSessions = listOf(otherPartySession)
))
}
}
}
Stack trace
java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
at net.corda.core.internal.concurrent.CordaFutureImpl.get(CordaFutureImpl.kt)
at com.maker.loyalty.TwoPartyCoreTests.Create token test EXPERIMENT(TwoPartyCoreTests.kt:91)
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.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Unknown entity: com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:788)
at net.corda.node.services.schema.PersistentStateService.persistStatesWithSchema$node(PersistentStateService.kt:48)
at net.corda.node.services.schema.PersistentStateService.persist(PersistentStateService.kt:40)
at net.corda.node.services.vault.NodeVaultService.processAndNotify(NodeVaultService.kt:393)
at net.corda.node.services.vault.NodeVaultService.access$processAndNotify(NodeVaultService.kt:54)
at net.corda.node.services.vault.NodeVaultService$notifyAll$1.invoke(NodeVaultService.kt:224)
at net.corda.node.services.vault.NodeVaultService$notifyAll$2.invoke(NodeVaultService.kt:235)
at net.corda.node.services.vault.NodeVaultService.notifyAll(NodeVaultService.kt:239)
at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:128)
at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:53)
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235)
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214)
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220)
at net.corda.node.services.api.ServiceHubInternal$Companion.recordTransactions(ServiceHubInternal.kt:72)
at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt:158)
at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
at net.corda.core.node.ServiceHub$DefaultImpls.recordTransactions(ServiceHub.kt:214)
at net.corda.core.internal.ServiceHubCoreInternal$DefaultImpls.recordTransactions(ServiceHubCoreInternal.kt)
at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt)
at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
at net.corda.core.node.ServiceHub$DefaultImpls.recordTransactions(ServiceHub.kt:206)
at net.corda.core.internal.ServiceHubCoreInternal$DefaultImpls.recordTransactions(ServiceHubCoreInternal.kt)
at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt)
at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:1008)
at net.corda.core.flows.FinalityFlow.notariseAndRecord(FinalityFlow.kt:205)
at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:147)
at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:39)
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
at com.r3.corda.lib.tokens.workflows.internal.flows.finality.ObserverAwareFinalityFlow.call(ObserverAwareFinalityFlow.kt:75)
at com.r3.corda.lib.tokens.workflows.internal.flows.finality.ObserverAwareFinalityFlow.call(ObserverAwareFinalityFlow.kt:35)
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
at com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow.call(IssueTokensFlow.kt:84)
at com.r3.corda.lib.tokens.workflows.flows.issue.IssueTokensFlow.call(IssueTokensFlow.kt:46)
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330)
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326)
at com.maker.loyalty.flows.IssueTokenExperiment$IssueNativeTokenToSelfInitializer.call(IssueTokenExperiment.kt:64)
at com.maker.loyalty.flows.IssueTokenExperiment$IssueNativeTokenToSelfInitializer.call(IssueTokenExperiment.kt:37)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46)
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(FutureTask.java:266)
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:63)
Fungible Token
import com.maker.loyalty.contracts.ParticipantNativeAccountContract
import com.maker.loyalty.schemas.ParticipantNativeTokenSchemaV1
import com.r3.corda.lib.tokens.contracts.internal.schemas.FungibleTokenSchema
import com.r3.corda.lib.tokens.contracts.internal.schemas.FungibleTokenSchemaV1
import com.r3.corda.lib.tokens.contracts.internal.schemas.PersistentFungibleToken
import com.r3.corda.lib.tokens.contracts.states.FungibleToken
import com.r3.corda.lib.tokens.contracts.types.IssuedTokenType
import com.r3.corda.lib.tokens.contracts.types.TokenType
import net.corda.core.contracts.Amount
import net.corda.core.contracts.BelongsToContract
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
import net.corda.core.serialization.CordaSerializable
import java.util.*
#BelongsToContract(ParticipantNativeAccountContract::class)
data class ParticipantNativeFungibleToken(override val amount: Amount<IssuedTokenType>,
override val issuer: Party,
val owner: Party,
val observers: List<AbstractParty> = listOf(),
override val participants: List<AbstractParty> = (mutableListOf(owner, issuer) + observers)
) : FungibleToken(amount, issuer), QueryableState {
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is FungibleTokenSchemaV1 -> PersistentFungibleToken(
issuer = issuer,
tokenIdentifier = amount.token.tokenIdentifier,
holder = owner,
tokenClass = amount.token.tokenClass,
amount = amount.quantity
)
// is ParticipantNativeTokenSchemaV1 -> ParticipantNativeTokenSchemaV1.PersistentParticipantNativeToken(
// issuer = issuer,
// tokenIdentifier = amount.token.tokenIdentifier,
// holder = owner,
// tokenClass = amount.token.tokenClass,
// amount = amount.quantity
// )
else -> throw IllegalArgumentException("Unrecognised schema $schema")
}
}
override fun supportedSchemas() = listOf(FungibleTokenSchemaV1)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ParticipantNativeFungibleToken
if (amount != other.amount) return false
if (holder != other.holder) return false
if (tokenTypeJarHash != other.tokenTypeJarHash) return false
return true
}
override fun hashCode(): Int {
var result = amount.hashCode()
result = 31 * result + holder.hashCode()
result = 31 * result + (tokenTypeJarHash?.hashCode() ?: 0)
return result
}
}
Test
#Test
fun `Issue token for self and notify the other party`() {
val resultFuture = a.startFlow(IssueTokenExperiment.IssueNativeTokenToSelfInitializer(
amount = 10L,
otherPartyX500Name = bNodeName
))
network.runNetwork()
val res = resultFuture.get()
assertNotNull(res)
}
#Before
fun setup() {
network.runNetwork()
setupClients()
addBonusToClientAccount()
}
#After
fun tearDown() = network.stopNodes()
private fun setupClients() {
a.startFlow(ClientAccountFlows.InitiateClientAccountCreation(person = defaultPerson))
b.startFlow(ClientAccountFlows.InitiateClientAccountCreation(person = defaultPerson))
network.runNetwork()
}
private fun addBonusToClientAccount() {
a.startFlow(ClientAccountFlows.AddBonusToClientAccount(person = defaultPerson, addedBonus = 100L))
b.startFlow(ClientAccountFlows.AddBonusToClientAccount(person = defaultPerson, addedBonus = 100L))
network.runNetwork()
}
gradle
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.quasar-utils'
cordapp {
targetPlatformVersion corda_platform_version
minimumPlatformVersion corda_platform_version
workflow {
name "Loyalty Flows"
versionId 1
}
}
sourceSets {
main {
resources {
srcDir rootProject.file("config/dev")
}
}
test {
resources {
srcDir rootProject.file("config/test")
}
}
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integrationTest/kotlin')
}
}
}
repositories {
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"
// Corda dependencies.
cordaCompile "$corda_release_group:corda-core:$corda_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
cordaCompile "$tokens_release_group:tokens-workflows:$tokens_release_version"
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
//tokens sdk
cordaCompile "$tokens_release_group:tokens-workflows:$tokens_release_version"
cordaCompile "$tokens_release_group:tokens-money:$tokens_release_version"
cordapp "$tokens_release_group:tokens-selection:$tokens_release_version"
// CorDapp dependencies.
cordapp project(":contracts")
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
You probably forgot to include the tokens-contracts dependency (which has the missing custom schema class mentioned in your error message) inside your node definition (i.e. inside deployNodes task in the root build.gradle file).
Add this line:
cordapp("$tokens_release_group:tokens-contracts:$tokens_release_version")
Remember to also include that dependency in the MockService of your contract tests and MockNetwork of your flow tests:
// Contract tests.
private final MockServices ledgerServices = new MockServices(
Collections.singletonList("com.r3.corda.lib.tokens.contracts"));
// Flow tests.
private final MockNetwork network = new MockNetwork(new MockNetworkParameters()
.withCordappsForAllNodes(ImmutableList.of(
TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"),

RxJava - Subscribe doesn't catch exception which cause crash

I am trying to subscribe to a SingleSource, I have implemented both onSuccess And onError of subscribe method, here is my code:
disposable.add(repository
.getUser1()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
toast(it)
}, {
toast(it.message ?: "Error")
}))
The Problem is When an exception occur in repository it does't being caught in onError
Here is my repository implementation:
class Repository(private val sp: SharedPreferences) {
// It crashes
fun getUser1(): Single<String> = generateUser(name, "Hello")
// it doesn't crash
fun getUser2(): Single<String> = Single.fromCallable { name }.flatMap { generateUser(it, "Hello") }
private var name: String
get() = sp.getString("user", null) ?: throw NoNameException()
set(value) = sp.edit().putString("user", value).apply()
private fun generateUser(name: String, message: String): Single<String> = Single.just("$message $name")
}
And here is the crash Log:
09-24 10:13:40.930 6934-6934/com.mosius.samplerxtest E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.mosius.samplerxtest, PID: 6934
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826) 
Caused by: com.mosius.samplerxtest.NoNameException: No Name Supplied
at com.mosius.samplerxtest.Repository.getName(Repository.kt:17)
at com.mosius.samplerxtest.Repository.getUser1(Repository.kt:10)
at com.mosius.samplerxtest.MainActivity$onCreate$1.onClick(MainActivity.kt:24)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25881)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6649)
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
What's the different between these two implementation?
In the getUser1() method, SingleSource has not been created yet, so it is out of Rx control to handle the exception.
In the Second one the name is being fetched in Rx scope therefore it could handle the exception

Java SAM interface created from Kotlin gives ClassCastException

I have a java method:
addHandler(HttpServiceHandler handler)
HttpServiceHandler is
interface HttpServiceHandler extends Consumer<HttpHandlerContext>
The point is to avoid Consumer<HttpHandlerContext> copy-paste across the project, so it's kind of a type alias.
In Java code, this works all right:
addHandler({ context -> context.blah(); })
Now, in Kotlin, I have this method that generates handlers:
private companion object {
fun newHandler(notimportant: Long): HttpServiceHandler {
return HttpServiceHandler { context -> context.blah() }
}
}
HttpServiceHandler {} is important, it doesn't compile if I don't specify HttpServiceHandler for the lambda.
And this compiles:
addHandler(newHandler(1L))
But at runtime, throws:
java.lang.ClassCastException: blah.BlahTest$Companion$newHandler$1 cannot be cast to kotlin.jvm.functions.Function1
at blah.BlahTest.test(BlahTest.kt:42)
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.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:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
And I can't figure out why. Help please?
Update: The class cast exception is gone if I write it like this:
addHandler(
object : HttpServiceHandler {
override fun accept(c: HttpHandlerContext) {
c.complete()
}
}
)
But still throws the exception when written like this:
fun newHandler(blah: Long): HttpServiceHandler {
return object : HttpServiceHandler {
override fun accept(c: HttpHandlerContext) {
c.complete()
}
}
}
addHandler(newHandler(1L))
And I have no idea why.
Update2: Test code at https://github.com/wilem82/testcases/tree/master/kotlinsam1 . Does not reproduce the problem, sadly.
the error has already said exactly:
java.lang.ClassCastException: blah.BlahTest$Companion$newHandler$1 cannot be cast to kotlin.jvm.functions.Function1
you try to cast a Consumer<HttpHandlerContext> to a Function1 in addHandler method or somewhere, for example:
fun addHandler(handler: Consumer<HttpHandlerContext>) {
val it: Function1<*, *> = handler as Function1<*, *>
// ^
// ClassCastException was thrown since it is not a Function1
}
you should using method reference expression in java / function reference expression in kotlin to convert a SAM interface to another SAM interface, for example:
fun addHandler(handler: Consumer<HttpHandlerContext>) {
val it: Function1<HttpHandlerContext, Unit> = handler::accept
// using function reference expression here ---^
//...
}
IF you call java method addHandler in kotlin, you needn't to create such a bridge method newHandler, you can just call it with lambda in kotlin, for example:
addHandler{context->
context.blah()
// additional works ...
}