-
-
Notifications
You must be signed in to change notification settings - Fork 1k
prevent stack overflow error for Immutables #3681
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
Conversation
…nt transformation is already complete
|
Thanks for the PR @Srimathi-S. I wasn't expecting any changes in the public API, I was expecting only changes in the |
…pe element transformation is already complete" This reverts commit 7e9afd6.
Thanks for the clarification @filiphr . Will it help to delegate the superClass builderInfo finding to ImmutableProvider that way there will not be any public api change. In DefaultBuilderProvider I can add the below method and implement in ImmutablesBuilderProvider with a custom call directed to super class Not sure how I can improvise the first step though. |
|
In theory what you can try is to add BuilderInfo findBuilderInfo( TypeMirror type, Set<TypeElement> processedTypeElementSet )to the However, looking at the test case public abstract class Item {
public abstract String getId();
public abstract Map<String, String> getAttributes();
public static Item.Builder builder() {
return new Item.Builder();
}
public static class Builder extends ImmutableItem.Builder {
public ImmutableItem.Builder addSomeData(String key, String data) {
return super.attributes( Map.of( key, data ) );
}
}
}To me it looks like that we should first check of the Currently, the assumption in |
|
@filiphr Sorry for the delayed response, I have thought about performing builder check on the super class of immutables first and then on immutables but there are 2 scenarios
If above is the class today there will be a builder generated inside immutable as well and till today we would have been using immutable class's builder but after this change we will start using the ItemDTO Builder. This sounds like an ideal behaviour though.
The only builder is there in BaseItemDTO it will be ideal for the code to switch over to this. In this case, we will end up encountering stack overflow error. There are two solutions I see possible now
to the DefaultBuilderProvider and from the existing method call the new method. Upside is this will also prevent any stack overflow errors. Downside is the new Public API addition and there are two tries before deciding to fallback to next super class.
and implement in ImmutablesBuilderProvider with a custom call directed to super class This will take the control of what to do with the next processing and give it to their corresponding subclass. They can choose to call their own findBuilderInfo or super class findBuilderInfo or something else whenever call fails. Upside is this will make sure the call is linear. Downside is we will not make the code preventative of stack overflow. |
|
Good points @Srimathi-S.
For this I would indeed agree that it would be more correct to use the builders that are defined you your own
This is a tricky one, as I'm not even sure that the builder on the base class will even be considered as a builder by MapStruct as we need to create I would prefer the second approach. You could even add a method protected BuilderInfo findBuilderInfo(TypeMirror type, boolean checkParent)that would be overwritten in the immutable implementation. My main thing is that we should only need to do small changes in the default implementation, in order for the immutables implementation to be able to overwrite certain methods. The public API of the SPI should not need changes I believe. I think that preventing a stackoverflow is on the implementation of the builder provider. Our current immutables implementation is not avoiding that as we always keep trying the existing class. An alternative would also be to first check the existing hierarchy and then check for the child |
|
@filiphr Sorry for the much delayed response. I have made the fixes to the MR as per your suggestions. Let me know if any further changes are needed. However, this will not work out-of-the-box as Immutables will generate the class without a You can refer test for this scenario. This behaviour is retained in latest version of immutables as well. |
|
Thanks for your work on this @Srimathi-S. I've pushed a small polish. Regarding the need for the user to define a static builder method. I think that is OK. What we could do (as a separate PR and if you are interested) is to look for inner static classes with a public constructor that could be a potential builder. |
|
Thanks @Srimathi-S |
Fixes #3370
Preiously:
(Immutable provider flow) Item -> ImmutableItem ->
(Base Provider flow) no builder -> Item ->
(Immutable provider flow) Item -> ImmutableItem ->
(Base Provider flow) no builder -> Item ->
continues
Current Behaviour
(Immutable provider flow) Item -> Item -> no builder -> ImmutableItem -> no builder -> super class of item
(Base Provider flow) usual class super class flow