在IntelliJ中运行Corda合约测试时,用Java编写的测试有时会失败,并出现以下异常:
[错误] 17:02:51,821 [主要] (Schema.kt:437) amqp.Schema.fingerprintForType - 构造函数参数 arg0 不引用类 'class mypackage 的属性。MyState' ->类 mypackage。我的状态 {} java.io.NotSerializableException:构造函数参数 arg0 不引用类 'class mypackage 的属性。我的状态' at net.corda.nodeapi.internal.serialization.amqp.SerializationHelperKt.propertiesForSerializationFromConstructor(SerializationHelper.kt:249) ~[corda-node-api-corda-3.0.jar:?]
我该如何解决这个问题?
正如 Joel 所解释的,默认情况下,编译的 Java 类将使用默认名称作为其构造函数参数。在 Corda 的情况下,我们应该对参数名称使用相同的名称,不是因为更好地识别它们中的每一个,或者它们非常漂亮以保持相同的名称,而是因为在 AMQP 通过自定义组件实现的序列化和反序列化过程中有一个验证,并专门重写到 Corda(corda-node-api)。此组件检查事务(合同状态)期间涉及的每个属性。提醒一下,在 Corda 中,所有序列化和反序列化都是受控的,如果发生冲突,可能会失败。
要解决此问题,有不同的形式,这取决于您使用哪种工具来自动编译 - gradle、maven 等。这是一个独立于IDE(Eclipse,IntelliJ等)的解决方案。
马文 - 绒球.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<compilerArgs>
<arg>-verbose</arg>
<arg>-parameters</arg> <!-- To keep parameter names-->
<arg>-Xlint:all,-options,-path</arg>
</compilerArgs>
</configuration>
</plugin>
有关传递编译器参数 Maven 的详细信息 https://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html
build.gradle - Gradle
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-Xlint:-options" << "-parameters"
}
有关 CompileOptions Gradle 的更多信息 https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
你可以在这里看到一篇关于如何设置编译选项的 StackOverflow 文章。 如何为 Gradle Java 插件设置编译选项?
默认情况下,编译的Java类将使用默认名称作为其构造函数参数(arg0
,arg1
等)。但是,出于序列化目的,我们需要实际的参数名称。您需要使用实际的参数名称进行 Java 编译。
在IntelliJ中:
如果通过 IntelliJ 运行节点/测试,则可以通过将以下块添加到.idea/compiler.xml
文件中来执行此操作:
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" />
</component>
或者转到IntelliJ IDEA
>Preferences
>Build, Execution, Deployment
>Compiler
>Java Compiler
并将-parameters
添加到Additional command line parameters:
框中。
要使 IntelliJ 获取编译器设置中的更改,请执行Build
>Rebuild Project
。
从命令行:
如果通过命令行运行节点/测试,则需要将以下代码片段添加到CorDapp每个模块的build.gradle
文件中:
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters" // Required for shell commands.
}
您可以在此处查看示例。