【问题标题】:Corda Service Failed to InstantiateCorda 服务无法实例化
【发布时间】:2019-12-21 04:13:03
【问题描述】:

我创建了一个自定义服务,我想在节点启动时运行它,如果该帐户不存在,则创建一个默认帐户。

我的班级:

import com.r3.corda.lib.accounts.workflows.services.AccountService
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService
import net.corda.core.node.AppServiceHub
import net.corda.core.node.services.CordaService
import net.corda.core.serialization.SingletonSerializeAsToken

@CordaService
class MyIdentityService(private val serviceHub: AppServiceHub) : SingletonSerializeAsToken() {
    init {
        val numberOfResults: Int = serviceHub.cordaService(KeyManagementBackedAccountService::class.java).accountInfo("acctName").size

        when(numberOfResults){
            0 -> {  println("Identity service account does not exist, account is being created...")
                    serviceHub.cordaService(KeyManagementBackedAccountService::class.java).createAccount("acctName")
                    println("Identity service account created.")
                }
            else -> println("Identity service account already exists.")
        }
    }
}

节点启动过程中的错误日志:

Identity service account does not exist, account is being created...
[ERROR] 04:53:44+0100 [main] internal.Node. - Corda service com.example.flows.MyIdentityService failed to instantiate. 
Reason was: null [errorCode=1gal9sv, moreInformationAt=https://errors.corda.net/OS/4.3-RC01/1gal9sv]

错误日志对于查找根本原因没有多大帮助。

我的服务定义有问题吗?
有没有人在使用自定义服务时遇到过类似的错误?

【问题讨论】:

  • KeyManagementBackedAccountService.createAccount 内部发生错误。在此函数中放置断点并使用 Intellij 启用远程调试。要启用远程调试,您必须在 Intellij 中创建 Remote Debugging 配置并使用以下命令启动节点:docs.corda.net/node-commandline.html#enabling-remote-debugging,一旦节点使用该命令启动;点击配置旁边的 bug 图标,Intellij 将附加到节点的 Java 进程,您可以开始跟踪 Intellij 内部正在运行的代码。
  • 感谢@AdelRustum 的建议。我会试一试并报告。

标签: kotlin corda


【解决方案1】:

在 Corda 中,没有关于多个 @CordaService 实例的初始化顺序的承诺。

Corda 只需遍历 cordapps/ 文件夹中的所有 CorDapps 并搜索 @CordaService 并将它们初始化为 Corda 进程中的单个实例服务。 在某些情况下,顺序可能始终相同,但不是承诺的,尤其是跨平台。

回到你的问题:在初始化阶段之后进行帐户检查和创建。

【讨论】:

  • 感谢您的澄清。我接受这个答案是正确的,我会留下我的答案作为参考。
【解决方案2】:

尽管这可能被认为是一种解决方法而不是解决方案,但我通过从 init 块中删除代码并创建了一个我从流程中调用的函数来解决了这个问题。

我无法弄清楚为什么从init 内部运行代码会返回错误,我认为代码已提前执行并且并非所有类都已正确加载。

更新代码为:

@CordaService
class MyIdentityService(private val serviceHub: AppServiceHub) : SingletonSerializeAsToken() {
    init {
        println("Identity Service is alive!")
    }

    @Suspendable
    fun createIdentityServiceAccount() : StateAndRef<AccountInfo> {
        val name: String = "myacctName"

        try {
            require(serviceHub.cordaService(KeyManagementBackedAccountService::class.java).accountInfo(name).none
            { it.state.data.host == serviceHub.myInfo.legalIdentities.first() })
            { "There is already an account registered with the specified name $name." }
        } catch (ex: Exception){
           println(ex.message)
           return serviceHub.cordaService(KeyManagementBackedAccountService::class.java).accountInfo(name).get(0)
        }
        return serviceHub.accountService.createAccount(name).toCompletableFuture().getOrThrow()
    }
}

【讨论】:

    猜你喜欢
    • 2021-11-13
    • 2014-07-27
    • 2011-06-28
    • 2012-08-04
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    相关资源
    最近更新 更多