-
-
Notifications
You must be signed in to change notification settings - Fork 2.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
[BUG] Jackson annotations are added in Builder even without @Jacksonized #3186
Comments
The I'm not quite sure if there is some logic to why jackson behaves like this or if this is a bug on their side; we're on v1.18.24, at this point removing this behaviour is just as disruptive, and you're the first to report it. Point being: There is no easy answer anymore. Really starting to regret attempting to address copying of annotations at all :( |
Thank you for your response. Would there be a way to maybe add a configuration setting to disable the copy of annotations ? I admit this might sound overkill if we're the first reporting it, but from my side it looks like we'll have to keep |
Actually I think a lighter solution like configuring a list of annotations we want to exclude from this logic would do the trick and would probably be more acceptable. I don't know if this is technically feasible though. |
It keeps coming up but I don't want to add it. The 'other' one where this keeps coming up proves why: Because blindly copying it is perhaps not the right move in the first place. I'm having a hard time accepting that there exists annotations for which it is logical to copy them exactly 95.000% of the time. Any less than that, and we shouldn't presume copying it was right in the first place. Any more than that, and whatever methods you want to exist that didn't get the copy are no longer boilerplate and you should just write it out by hand. Lombok cannot become a mess o' config options, that is not a route towards a library that is easy to maintain, explain, and use. This particula case sounds more like: You're doing something sufficiently bizarre that you should write the methods out long-form. Have some patience with me - I don't use Jackson much. Is there a way to explain to me (as a non-jackson user) why the need to not copy these would plausibly come up? |
I totally agree and understand why you don't want to add it.
A problem will come up especially with
Hence the breaking change implied by Lombok upgrade for users who might not correctly follow the expected format. But to be honest, this is an issue because we thought Jackson was strict all along even for deserialization, but it appears that if you tell it to use the Builder to deserialize, then the enforcement is done only if annotations are copied to the Builder. In the end, having Lombok copying this annotation is not wrong to me. I'd just wish it wasn't, for this specific situation :)
Is there a way, on our side, to "undo" the copy done by lombok for this specific annotation |
Just an idea (lacking a PC to test it at the moment): If we're lucky, that already works. If not, I think that could be something to address in a new lombok release. It's a potential breaking change, but it's very unlikely, because it would affect only repeatable annotations, as this is the only way to allow multiple annotations of the same type. And even if it breaks someone's code, that's easily fixable by manually adding the annotation a second time. And I don't know if there are even repeatable annotations in the annotations-to-copy list. |
Thank you very much, your suggestion seems to work as expected :
@JsonPOJOBuilder(withPrefix = "")
public static final class ExpenseBuilder {
@JsonFormat(lenient = OptBoolean.TRUE)
public ExpenseBuilder date(LocalDateTime date) {
this.date = date;
return this;
}
}
@JsonPOJOBuilder(
withPrefix = ""
)
public static final class ExpenseBuilder {
private LocalDateTime date;
@JsonFormat(
lenient = OptBoolean.TRUE
)
public ExpenseBuilder date(LocalDateTime var1) {
this.date = var1;
return this;
}
ExpenseBuilder() {
}
public Expense build() {
return new Expense(this.date);
}
public String toString() {
return "TestJacksonLombok.Expense.ExpenseBuilder(date=" + this.date + ")";
}
} Then I guess we have a way to work around this, I'll close this issue. |
I'll make a separate issue for it, but I'm strongly considering a completely different approach to automatic annotation copying. The new plan is: We don't, instead, you add a single line to lombok.config naming your 'library' (not any individual annotation) and we do the right thing for it, automatically. This means it's now opt-in, there won't be 'surprises' (Where some point-release update of lombok causes some annotation to be silently copied whereas before we didn't), we can 'crash' if we don't recognize the key (that would indicate you need to upgrade lombok first / someone with a newer version added it), and we have a place to document it, at least. With as one exception: Any annotations that are specifically about nullity at the language level (and not, say, at the 'when you make a table in some SQL database to model this type, stick a non-null constraint on it', so javax.validation doesn't count, as an example) - we support those inherently, including copying them, and will silently add new ones in newer lombok versions if some well meaning dweeb adds the 85th different take on nonnull annotations. Please don't do that, but if you must, let us know. It has to be public and meant for general consumption (not your own internal nonnull annotation used solely within a single project or company or team). |
Describe the bug
After upgrading from
1.18.12
to1.18.16
, Jackson annotations likeJsonFormat
,JsonIgnore
, ... are copied from Class members to setter and the accordingBuilder
fields.This looks a lot like the
@Jacksonized
feature introduced in1.18.16
with #2387, but the problem is that I don't use this annotation, and the logic seems to be applied anyway.For instance, for this initial java file...
I have the following vanilla java files :
1.18.16
:1.18.12
:So with
1.18.16
, Jackson annotations are now copied to Builder (and also Class setter), even without@Jacksonized
annotation.To Reproduce
Compile the following file :
$ curl -s https://repo1.maven.org/maven2/org/projectlombok/lombok/1.18.16/lombok-1.18.16.jar -O $ curl -s https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.13.2/jackson-annotations-2.13.2.jar -O $ curl -s https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.13.2/jackson-core-2.13.2.jar -O $ curl -s https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.13.2.2/jackson-databind-2.13.2.2.jar -O $ javac -cp "*" TestJacksonLombok
curl -s https://repo1.maven.org/maven2/org/projectlombok/lombok/1.18.12/lombok-1.18.12.jar -O
, you will see there is no issue with1.18.12
.Expected behavior
If I'm correct assuming this is an issue with
@Jacksonized
, its logic shouldn't be applied if@Jacksonized
isn't explicitly set.Version info (please complete the following information):
1.18.16
Additional context
When
JsonFormat
is copied to the Builder, it makes the deserialization stricter as you can't rely on Jacksonlenient
logic if apattern
is defined.So in the case you're maintaining an API, before
1.18.16
users are able to use slightly different format than the one you defined (slightly different but still valid for Jackson depending on the expected type, though), i.e. maybe by mistake they are not strictly using the milliseconds for aLocaleDateTime
for instance.But after
1.18.16
, this tolerance is gone because theJsonFormat
is defined at Builder level, and if apattern
is defined, enablinglenient
setting has no effect. So this is a breaking change for your API users who don't have choice to use strictly the format you defined. We'd like to avoid having this consequence by default.The text was updated successfully, but these errors were encountered: