mercredi 3 mai 2023

Invoke a method which returns an object from a specific class

I have a Java method that I am going to call using reflection, but it throws an UnsupportedOperationException: invalid class reference provided:

package example;

public class TestContract extends Contract {
     
    // .. other functions they are not intended

     public RemoteFunctionCall<User> ret1Object() {
          final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(FUNC_RET1OBJECT, 
                  Arrays.<Type>asList(), 
                  Arrays.<TypeReference<?>>asList(new TypeReference<User>() {}));
          return executeRemoteCallSingleValueReturn(function, User.class);
     }

     public static class Person extends StaticStruct {
        public BigInteger size;

        public Person(BigInteger size) {
            super(new org.web3j.abi.datatypes.generated.Uint256(size));
            this.size = size;
        }
    }

    public static class User extends DynamicStruct {
        public String name;

        public String fr2;

        public BigInteger age;

        public Person person;

        public User(String name, String fr2, BigInteger age, Person person) {
            super(new org.web3j.abi.datatypes.Utf8String(name), 
                    new org.web3j.abi.datatypes.Address(160, fr2), 
                    new org.web3j.abi.datatypes.generated.Uint8(age), 
                    person);
            this.name = name;
            this.fr2 = fr2;
            this.age = age;
            this.person = person;
        }
    }

}

Note that the above function (ret1Object) is returning a User object. (No problem when a method returns String, BigInteger, etc.)

I'm using the following code to call functions at runtime:

ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("example.TestContract");
Method loadMethod = cls.getMethod("load", String.class, Web3j.class, Credentials.class, ContractGasProvider.class);
Object instance = 
                    loadMethod.invoke(cls, contractAddress, AIOBlock.web3Instance, AIOBlock.currentCredential, (ContractGasProvider) new DefaultGasProvider());

Method[] methods = cls.getMethods();
Method method = null;
for (Method mth : methods) {
    if (mth.getName().equalsIgnoreCase("ret1Object")) {
        method = mth;
        break;
    }
}
Object retObject = method.invoke(instance);
RemoteFunctionCall rfc = (RemoteFunctionCall) retObject;
retObject = rfc.send(); // <<----------- Exception is thrown at this line

When calling ret1Object I'm getting the exception invalid class reference provided, but my code works for all other functions that return java built-in types such as String, BigInteger, etc.





Aucun commentaire:

Enregistrer un commentaire