java.io.NotSerializableException:构造函数参数 arg0 不引用类的属性



在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类将使用默认名称作为其构造函数参数(arg0arg1等)。但是,出于序列化目的,我们需要实际的参数名称。您需要使用实际的参数名称进行 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.
}

您可以在此处查看示例。

最新更新