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

时间:2018-02-13 17:18:23

标签: corda

在IntelliJ中运行Corda合同测试时,用Java编写的测试有时会失败,但会出现以下异常:

  

[ERROR] 17:02:51,821 [main](Schema.kt:437)amqp.Schema.fingerprintForType - 构造函数参数arg0不引用类'class mypackage.MyState'的属性 - > class mypackage.MyState {}   java.io.NotSerializableException:构造函数参数arg0不引用类'class mypackage.MyState'的属性       at net.corda.nodeapi.internal.serialization.amqp.SerializationHelperKt.propertiesForSerializationFromConstructor(SerializationHelper.kt:249)〜[corda-node-api-corda-3.0.jar:?]

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

正如Joel所解释的,默认情况下,编译的Java类将使用默认名称作为其构造函数参数。在Corda的情况下,我们应该为参数名称使用相同的名称,不是因为更好地识别每个参数名称或者它们是如此美丽以保持相同的名称,但是因为在AMQP通过AMQP实现的序列化和反序列化期间进行了验证一个专门为Corda(corda-node-api)定制和重写的组件。此组件检查Transaction(ContractState)期间涉及的每个属性。提醒一下,在Corda中,所有的序列化和反序列化都是可控制的,如果出现问题,可能会失败。

要解决这个问题,有不同的形式,它取决于您使用哪个工具来自动化编译 - gradle,maven等。这是一个独立于IDE(Eclipse,IntelliJ等)的解决方案。

Maven - pom.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>

有关Pass Compiler Arguments 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帖子质疑如何在此处设置compileOptions How can I set the compileOptions for my Gradle Java plugin?

答案 1 :(得分:3)

默认情况下,已编译的Java类将使用默认名称作为其构造函数参数(arg1.idea/compiler.xml等)。但是,我们需要实际的参数名称才能进行序列化。您需要使用实际参数名称进行Java编译。

在IntelliJ中:

如果通过IntelliJ运行节点/测试,您可以通过将以下块添加到<component name="JavacSettings"> <option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" /> </component> 文件来执行此操作:

IntelliJ IDEA

或者转到Preferences&gt; Build, Execution, Deployment&gt; Compiler&gt; Java Compiler&gt; -parameters并将Additional command line parameters:添加到Build框。

要使IntelliJ选择编译器设置中的更改,请执行Rebuild Project&gt; build.gradle

从命令行:

如果通过命令行运行节点/测试,则需要将以下代码段添加到每个CorDapp模块的tasks.withType(JavaCompile) { options.compilerArgs << "-parameters" // Required for shell commands. } 文件中:

{{1}}

您可以看到示例here