1
votes

Trying to migrate from Corda V1 to V3. It was working fine in V1 but after using Corda V3 its throwing below error -

java.util.concurrent.ExecutionException: java.io.NotSerializableException: net.corda.core.contracts.TransactionState -> data(net.corda.core.contracts.ContractState) -> Defined setter for parameter eligibleCurrency takes parameter of type interface java.util.List yet underlying type is java.util.List -> class com.xxx.agreementnegotiation.state.AgreementNegotiationState

at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) atjava.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at net.corda.core.internal.concurrent.CordaFutureImpl.get(CordaFutureImpl.kt) at com.xxx.agreementnegotiation.api.AgreementNegotiationApi.startInitFlow(AgreementNegotiationApi.java:95) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:267) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:535) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:561) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:334) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:104) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:243) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:679) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:597)

at java.lang.Thread.run(Thread.java:748) Caused by: java.io.NotSerializableException: net.corda.core.contracts.TransactionState -> data(net.corda.core.contracts.ContractState) -> Defined setter for parameter eligibleCurrency takes parameter of type interface java.util.List yet underlying type is java.util.List -> class com.xxx.agreementnegotiation.state.AgreementNegotiationState

Some part of my state

public class AgreementNegotiationState extends AgreementStateTemplate implements QueryableState {
private String baseCurrency;
private List<String> eligibleCurrency;
private int deliveryAmount;

public String getBaseCurrency() {
    return baseCurrency;
}

public void setBaseCurrency(String baseCurrency) {
    this.baseCurrency = baseCurrency;
}

public List<String> getEligibleCurrency() {
    return eligibleCurrency;
}

public void setEligibleCurrency(List<String> eligibleCurrency) {
    this.eligibleCurrency = eligibleCurrency;
}

public int getDeliveryAmount() {
    return deliveryAmount;
}

public void setDeliveryAmount(int deliveryAmount) {
    this.deliveryAmount = deliveryAmount;
}

}

Please assist.

2

2 Answers

0
votes

This is a bug in Corda 3. It will be fixed in Corda 4.

In the meantime, the workaround is to change eligibleCurrency to a List<?>, and cast its elements as required:

private List<?> eligibleCurrency;

public List<?> getEligibleCurrency() {
    return eligibleCurrency;
}

public void setEligibleCurrency(List<?> eligibleCurrency) {
    this.eligibleCurrency = eligibleCurrency;
}
0
votes

As per corda V3 , Collections are immutable so you cannot add to the existing collection.The Solution is create a function which take the copy of the existing collection and add the item in it and finally referenced it to the eligibleCurrency list.

private Collection<SupportingDocument> supportingDocs;
public void addSupportingDoc(SupportingDocument supportingDoc) {

    //since corda 3.1 has unmodifiable collection
    List<SupportingDocument> suppDoc = new ArrayList<SupportingDocument>();
    for(SupportingDocument existingDoc : supportingDocs){
        suppDoc.add(existingDoc);
    }
    // adding new document
    suppDoc.add(supportingDoc);
    this.supportingDocs = Collections.unmodifiableCollection(suppDoc);
}

I hope , it makes sense