mapstruct icon indicating copy to clipboard operation
mapstruct copied to clipboard

Stackoverflow with Immutables custom builder

Open creckord opened this issue 2 years ago • 6 comments

Expected behavior

I have a value object making use of Immutables, which requires a customized builder class. It's defined like this:

@Value.Immutable
public abstract class ValueObject {
    public abstract String getFoo();
    public abstract Long getId();

    public static class Builder extends ImmutableValueObject.Builder {
       //some additional builder methods here
    }
}

And a POJO entity class like this:

public class ValueEntity {
    private String foo;
    protected Long id;

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getFoo() { return foo; }
    public void setFoo(String foo) { this.foo = foo; }
}

And a simple Mapper definition that maps ValueEntity to ValueObject:

@Mapper
public abstract class Converter {
    public abstract ValueObject convert(ValueEntity valueEntity);
}

Expectation: The mapper implementation ConverterImpl is generated successfully and uses the builder generated by Immutables to create the ValueObject.

Actual behavior

Generating the mapper fails with a StackOverflowError in the annotation processor:

  	at org.mapstruct.ap.spi.ImmutablesBuilderProvider.findBuilderInfoForImmutables(ImmutablesBuilderProvider.java:58)
  	at org.mapstruct.ap.spi.ImmutablesBuilderProvider.findBuilderInfo(ImmutablesBuilderProvider.java:40)
  	at org.mapstruct.ap.spi.DefaultBuilderProvider.findBuilderInfo(DefaultBuilderProvider.java:96)
  	at org.mapstruct.ap.spi.DefaultBuilderProvider.findBuilderInfo(DefaultBuilderProvider.java:185)
  	at org.mapstruct.ap.spi.ImmutablesBuilderProvider.findBuilderInfoForImmutables(ImmutablesBuilderProvider.java:58)
  	at org.mapstruct.ap.spi.ImmutablesBuilderProvider.findBuilderInfo(ImmutablesBuilderProvider.java:40)
  	at org.mapstruct.ap.spi.DefaultBuilderProvider.findBuilderInfo(DefaultBuilderProvider.java:96)

Steps to reproduce the problem

Clone https://github.com/creckord/mapstruct-immutables-mcve and run ./gradlew clean classes

MapStruct Version

1.5.5

creckord avatar Sep 01 '23 14:09 creckord

The mapper is created just fine as soon as I remove the inner Builder class, no matter its content.

creckord avatar Sep 01 '23 14:09 creckord

Also note that specifying the mapping method as

    public abstract ImmutableValueObject.Builder convert(ValueEntity valueEntity);

works.

Specifying it like this

    public abstract ValueObject.Builder convert(ValueEntity valueEntity);

makes the compiler give up with strange compile errors:

error: incompatible types: de.postadress.ars.ImmutableValueObject.Builder cannot be converted to de.postadress.ars.ValueObject.Builder
      if (!(this instanceof ValueObject.Builder)) {

creckord avatar Sep 01 '23 14:09 creckord

Thanks for the repo @creckord. The problem is the fact that we are always trying to determine the ImmutableXXX.Builder type. Seems like that Immutables has added support for defining a custom builder within the immutable type itself. This means that we need to improve our support for this.

I'll put this as up for grabs in case someone from the community is interested in helping us out with this.

filiphr avatar Sep 10 '23 22:09 filiphr

@filiphr Have raised an MR for the fix of this issue please check and let me know. Also I am not able to see or trigger checks tests ran fine on my local.

Srimathi-S avatar Aug 22 '24 19:08 Srimathi-S

@Srimathi-S what is failing is the breaking of the API. If you do mvn clean install you should be able to see the errors as well. They are not test errors

filiphr avatar Aug 24 '24 10:08 filiphr

Thanks able to see them on local as well now.

Srimathi-S avatar Aug 24 '24 19:08 Srimathi-S