Skip to content

Can't generate object when same generic placeholder is used for multiple fields #305

@lmbnaylor

Description

@lmbnaylor

Problem description: When a class uses a generic type and inherits from a class that uses the same placeholder for a different generic type, generating an object produces an argument mismatch.

Example classes:

public class TestObject<T extends GenericType> extends ParentObject<Short>{

    private T genericType;

    public T getGenericType() {
        return this.genericType;
    }

    public void setGenericType(T genericType) {
        this.genericType = genericType;
    }
}
public class GenericType {
    private String name;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class ParentObject<T extends Serializable> {
    private T id;

    public T getId() {
        return this.id;
    }

    public void setId(T id) {
        this.id = id;
    }
}

Running
new PodamFactoryImpl().manufacturePojo(TestObject.class, GenericType.class) produces

Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at uk.co.jemos.podam.api.PodamFactoryImpl.populateReadWriteField(PodamFactoryImpl.java:846)
	at uk.co.jemos.podam.api.PodamFactoryImpl.populatePojoInternal(PodamFactoryImpl.java:615)
	at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:525)
	at uk.co.jemos.podam.api.PodamFactoryImpl.doManufacturePojo(PodamFactoryImpl.java:428)
	at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:150)
	at org.example.Main.main(Main.java:16)

Because T corresponds to two different types, the typeArgsMap in TypeManufacturerUtil#fillTypeArgMap will add a mapping from T -> GenericType, but gets overridden with T -> Short, so it attempts to populate the genericType field with a Short instead of GenericType

In this simple example, it is trivial to switch the placeholder in ParentObject so there is no overlap, but this remains an issue when you are not able to update the source code; perhaps typeArgsMap could be updated to Map<Class, Map<String, Type>> so that the same placeholder could be used between different classes?

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions