question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot Inherit from Generated Factory Builder

See original GitHub issue

Given the following class:

import org.immutables.builder.Builder.Constructor;
import org.immutables.value.Value;

@Value.Style(visibility=Value.Style.ImplementationVisibility.PACKAGE)
public class Foo {
    private final String bar;
    private final String baz;

    @Constructor
    /*package-private*/ Foo(final String bar, final String baz) {
        this.bar = bar;
        this.baz = baz;
    }

    public static class Builder extends FooBuilder {
    }

    public static Builder builder() {
        return new Builder();
    }
}

The output of the generated factory builder is a final class:

@Generated(from = "Foo", generator = "Immutables")
@SuppressWarnings({"all"})
@SuppressFBWarnings
@ParametersAreNonnullByDefault
@javax.annotation.Generated("org.immutables.processor.ProxyProcessor")
@NotThreadSafe
public final class FooBuilder {
  private static final long INIT_BIT_BAR = 0x1L;
  private static final long INIT_BIT_BAZ = 0x2L;
  private long initBits = 0x3L;

  private @Nullable String bar;
  private @Nullable String baz;

Resulting in the following compilation failure:

Foo.java:15: error: cannot inherit from final FooBuilder
    public static class Builder extends FooBuilder {
                                        ^
1 error

When following this same pattern with Immutable builders, the builder is generated as a non-final class.

Would it be possible to achieve parity between normal immutable builders and factory builders in this respect?

Thanks.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
Sarev0kcommented, Sep 3, 2019

Actually I take it back, I don’t think what you describe will solve my issue, because I need some level of overshadowImplementation to work, otherwise I won’t be able to use the chained builders from the derived type.

Ideally I’d like to be able to define my class like so:

@Value.Style(builderVisibility=Value.Style.BuilderVisibility.PACKAGE, overshadowImplementation=true)
public class Foo {
    private final String bar;
    private final String baz;

    @Constructor
    /*package-private*/ Foo(final String bar, final String baz) {
        this.bar = bar;
        this.baz = baz;
    }

    public static class Builder extends FooBuilder {
    }

    public static Builder builder() {
        return new Builder();
    }
}

And initialize it like:

Foo foo = Foo.builder()
             .setBar("bar")
             .setBaz("baz")
             .build()
0reactions
ambition-consultingcommented, Sep 17, 2021

I was also surprised - especially that this is still open? I would also really like to customise the builder, which is currently final and has only private constructor - at least for staged/strict builders.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using generated builders of inherited classes when the ...
The automapper I'm using, AutoMatter, allows inheritance, e.g. @AutoMatter public interface BaseClass { Foo foo(); Bar bar(); } ...
Read more >
Lombok @Builder with Inheritance - Baeldung
In this short tutorial, we're specifically going to learn how to deal with the @Builder annotation when inheritance is involved.
Read more >
Factory Pattern with Inheritance - Monday Morning Confusion
The factory pattern does not look at concrete classes to create an implementation. Rather, it chooses a concrete class based on a given...
Read more >
Inheritance/Composition VS "Direct Injection Construction"
So the problem is with the Builder (which creates an composition-Object) or Inheritance, that I must create some extra class to get a...
Read more >
Factory method pattern - Wikipedia
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of ... having...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found