Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] SuperBuilder's builder method with unbound generics forces casting down the route... #3445

Open
lbreuss opened this issue Jun 30, 2023 · 5 comments

Comments

@lbreuss
Copy link

lbreuss commented Jun 30, 2023

Describe the bug
The builder() method of @SuperBuilder returns a Builder with unbound generics, which causes problems down the lane.

@SuperBuilder
public class MembershipEntity {
    String topic;
}

a Test method:

    // compile error: 
    public List<MembershipEntity> generate() {
        return List.of(MembershipEntity.builder().topic("TEST").build());
    }

compile error:
Required type: List<MembershipEntity>
Provided: List<? extends MembershipEntity>

The problematic delomboked Vanilla code:

    public static MembershipEntityBuilder<?,?> builder() {
        return new MembershipEntityBuilderImpl();
    }

Workaround
I have to cast the result of the builder, which is quite ugly and cumbersome:

    public List<MembershipEntity> generateCasted() {
        return List.of(((MembershipEntity)(MembershipEntity.builder().topic("TEST").build())));
    }

Or I could provide my own implementation of builder without generics in every @SuperBuilder annotated class:

    public static MembershipEntityBuilder builder() {
        return new MembershipEntityBuilderImpl();
    }

This does not work for toBuilder() tough, which has the same problem...

Expected behavior
I would like to have no generics at all, or properly bound generics for the above case to work.

    public static MembershipEntityBuilder builder() {
        return new MembershipEntityBuilderImpl();
    }

Version info :

  • Lombok version 1.18.26
  • Platform: IntelliJ, JDK javac 11.0.19
@lbreuss
Copy link
Author

lbreuss commented Jun 30, 2023

#2708, eventually related to this issue

@Rawi01
Copy link
Collaborator

Rawi01 commented Jul 1, 2023

The build method is the important one, the builder doesn't matter. As far as I know it always returns a non-generic type. Can you please check your imports and verify that you use the jdk List?

@lbreuss
Copy link
Author

lbreuss commented Jul 1, 2023

Thanks for the prompt answer. Yes, it's java.util.List, I verified.

Indeed, the delomboked code shows that build() returns the desired class, but still I get the above error. Can you reproduce the compiler error stated above with the simple test method?

Let me show you the relevant code:

@SuperBuilder
public class MembershipEntity extends PersistenceEntity {
    private String topic;

    public static MembershipEntityBuilder<?, ?> builder() {
        return new MembershipEntityBuilderImpl();
    }

    public static abstract class MembershipEntityBuilder<C extends MembershipEntity, B extends MembershipEntityBuilder<C, B>> extends PersistenceEntityBuilder<C, B> {
        private String topic;

        public B topic(String topic) {
            this.topic = topic;
            return self();
        }

        protected B $fillValuesFrom(C instance) {
            super.$fillValuesFrom(instance);
            MembershipEntityBuilder.$fillValuesFromInstanceIntoBuilder(instance, this);
            return self();
        }
        protected abstract B self();
        public abstract C build();
    }

    private static final class MembershipEntityBuilderImpl extends MembershipEntityBuilder<MembershipEntity, MembershipEntityBuilderImpl> {
        protected MembershipEntityBuilderImpl self() {
            return this;
        }
        public MembershipEntity build() {
            return new MembershipEntity(this);
        }
    }

If the builder() method really needs generics, it's probably a bit more of generics acrobatics than just <?,?>. Didn't have time to investigate myself yet. generics sometimes require super powers. ;-)

@janrieke
Copy link
Contributor

janrieke commented Jul 7, 2023

I cannot reproduce this. This code compiles perfectly with both Eclipse and javac:

@SuperBuilder
public class MembershipEntity {
    String topic;
    
    public List<MembershipEntity> generate() {
        return List.of(MembershipEntity.builder().topic("TEST").build());
    }
}

I'm not using IntelliJ, maybe it's a problem just for the IntelliJ compiler?

@lbreuss
Copy link
Author

lbreuss commented Jul 7, 2023

I'll double check in 3 weeks... thanks so far for retesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants