0
votes

I'm writing a cordapp where I need to use state classes that require a custom serializer. I have got one defined according to the documentation, but it does not seem to be picked up when I'm trying to run contract tests via corda-node-driver (exactly as per corda-helloworld template).

Here is the class definition (suitably obfuscated):

public class BlahBlahSerializer implements SerializationCustomSerializer<BlahBlah, BlahBlahProxy> {
  public IOUState fromProxy(BlahBlahProxy proxy) {
    /* impl */
  }

  public BlahBlahProxy toProxy(BlahBlah state) {
    /* impl */
  }
}

}

The .class file for the above is in the cordap jar created by the driver, and so are the BlahBlahProxy.class, contract and state classes. All these classes are is in the same package as the state and contract classes themselves.

I have enabled DEBUG logging for corda and I can see a lot of lines like this one

[Test worker] CachingCustomSerializerRegistry - action="Using custom serializer", class=java.security.PublicKey, declaredType=java.security.PublicKey

but there isn't a line for my class.

I wonder if there is anything else I need to do to enable custom serializer to be picked up?

1
Which version of Corda are you using? OS 4.3? I ask because we fixed in issue with classgraph not always loading URL attachments (something was wrong where it wouldn't correctly scan them). To fix we updated classgraph to 4.8.58 in OS 4.4 (and Enterprise versions) - fowlerrr
Yes, it's OS 4.3. I'll check if it works in 4.4, thanks for the info! - Igor
@igor I have a similar issue, and looking at the code, it seems that tests are always run in a serialization environment that ignores custom serializers defined in the cordapps. Did you find a solution to this? - Ulrik Rasmussen
@UlrikRasmussen I did not, just managed to work around this for now. But that's exactly what I experienced. Waiting for OS 4.4 to be released to released to try again - Igor

1 Answers

0
votes

I think @fowlerr is relatively correct may have been an issue with this in the past.

Take a look at the latest version of Corda (4.5) and see if you can get a custom serializer work there. Hopefully, you won't have issues with something like this :

 /**
 * The class lacks a public constructor that takes parameters it can associate
 * with its properties and is thus not serializable by the CORDA serialization
 * framework.
 */
class Example {
    private int a;
    private int b;

    public int getA() { return  a; }
    public int getB() { return  b; }

    public Example(List<int> l) {
        this.a = l.get(0);
        this.b = l.get(1);
    }
}

/**
 * This is the class that will Proxy instances of Example within the serializer
 */
public class ExampleProxy {
    /**
     * These properties will be serialized into the byte stream, this is where we choose how to
     * represent instances of the object we're proxying. In this example, which is somewhat
     * contrived, this choice is obvious. In your own classes / 3rd party libraries, however, this
     * may require more thought.
     */
    private int proxiedA;
    private int proxiedB;

    /**
     * The proxy class itself must be serializable by the framework, it must thus have a constructor that
     * can be mapped to the properties of the class via getter methods.
     */
    public int getProxiedA() { return proxiedA; }
    public int getProxiedB() { return  proxiedB; }

    public ExampleProxy(int proxiedA, int proxiedB) {
        this.proxiedA = proxiedA;
        this.proxiedB = proxiedB;
    }
}

/**
 * Finally this is the custom serializer that will automatically loaded into the serialization
 * framework when the CorDapp Jar is scanned at runtime.
 */
public class ExampleSerializer implements SerializationCustomSerializer<Example, ExampleProxy> {

    /**
     *  Given an instance of the Example class, create an instance of the proxying object ExampleProxy.
     *
     *  Essentially convert Example -> ExampleProxy
     */
    public ExampleProxy toProxy(Example obj) {
        return new ExampleProxy(obj.getA(), obj.getB());
    }

    /**
     * Conversely, given an instance of the proxy object, revert that back to an instance of the
     * type being proxied.
     *
     *  Essentially convert ExampleProxy -> Example
     */
    public Example fromProxy(ExampleProxy proxy) {
        List<int> l = new ArrayList<int>(2);
        l.add(proxy.getProxiedA());
        l.add(proxy.getProxiedB());
        return new Example(l);
    }
}

source from docs: https://docs.corda.net/docs/corda-os/4.4/cordapp-custom-serializers.html#writing-a-custom-serializer