-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Support specifying method for instantiating builders in JsonDeserialize #2354
Comments
Is there any progress on this? I'm the contributor of the
This is highly error-prone and unnecessarily clutters the source code with a class definition most users won't understand why it's there. The only solution I see here for lombok is to make the builder implementation class package-private by default (instead of If you do not see any fundamental problems with adding such a parameter to |
Hmm, now I'm a bit confused. I just checked it again and it also works with the builder implementation class |
@janrieke Build implementation class should work any protection level (at least with Java 8, 9 and later may limit accessibility, esp. for |
@kaweston On original request: I guess I can see potential benefit of allowing specifying a static factory method for constructing Builder, instead of relying on Builder having a no-argument constructor. Is that what and why it is requested? As per above, access restrictions should not require separate builder implementation, and no-arg constructor can remain private or package protected, needs not be public (and same for impl class). I also noticed that the example did not use the suggested new annotation. |
IIRC the problem was not within Jackson, but that I got a compilation error on the annotation when referencing the (private) builder implementation class. |
I found the problem: Eclipse's compiler does not complain about private access, but So allowing specifying a static factory method would in fact help. |
@cowtowncoder I raised the issue primarily on the basis that this was causing a compilation issue. I wasn't sure whether not being able to instantiate the private class was by design or a bug. Having said that, I'm personally of the view that things marked private shouldn't have their protection level subverted unless there is no other way. In this case there is an alternative with a builder method when specified. Additionally, the fact that builder methods for instantiating builder classes is such a common pattern (for reasons such as not forcing a no arg constructor as you pointed out) it is something, I think, would be quite widely welcomed and hence I would advocate support for specifying a builder method irrespective of whether a change is made to support instantiating private classes (with javac given @janrieke's findings). |
@kaweston Ok. So I'll consider this an RFE that is still open. Just one additional note: as far as I can see Jackson can access private (inner) classes as well as methods just fine. No changes needed. This with Java 8; module system may impose further limits to require module declarations to "open" access for reflection. |
Here is the relevant part of the JLS (section 6.6.1.):
The important part is "within the body of the top level type". As the annotation is placed outside the body of the outer class, javac is correct to complain that the nested private class is not accessible. If this compiles in javac 8 (I can't verify that right now), I'm quite sure the behavior of javac 8 would be incorrect (and that javac 9 complains is more likely a bugfix than a result of the module system). The test you introduced in b448a2a only compiles because you have a top-level type around the nested class that has the annotation. Thus, the annotation is within the body of the top-level type. IMO the JLS is not very consistent at this point (my guess is that this definition existed before generics and annotations were introduced). |
Ah, interesting. My interest in test was more wrt actual dynamic access, but then again with CI system it could catch changes to ability compile too (should warnings become errors). Either way, this is useful information as it makes the case for addition of method stronger. I'll have to see if this would be doable for 2.11, given that it requires annotation addition (but to annotation that is in databind, one of few) |
One additional note: unfortunately
so slightly bigger change needed to pass information. Not a big deal, I hope; not aware of others using this extension point... but there's no good way to really figure it out. |
I request adding a parameter such as
builderMethod
toJsonDeserialize
(e.g.@JsonDeserialize(builderMethod = "builder")
) to facilitate a way of specifying a method to instantiate a builder instance.Example use case
When using the Lombok SuperBuilder annotation it results in the creation two builder inner classes, one public and the other private which subclasses the public; it is the private class that must be instantiated. Currently when using the SuperBuilder annotation it is necessary to declare the private inner class (which will be completed during the annotation processing stage) to set its access modifier to package private so that Jackson can instantiated it.
An example original source file and the annotation processed result follows:
Original file
After annotation processing
The text was updated successfully, but these errors were encountered: