-
-
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
Ensure Constructor Parameter annotations are linked with those of Field, Getter, or Setter #792
Comments
Note that the above examples assume the presence of the Parameter Names module or other mechanism for recognizing the property corresponding to the constructor parameter. |
Actually: the fix checked in 2.5 should cover your case, I think. My version of the test was bit different, and problem there was that the non-public field wasn't being used, but that should not be necessary when there is a visible getter. Plus I can see if non-public getter handling, when a visible creator is available, could be "pulled in". |
I haven't yet tested the patch, but if non-public fields are still an issue there may still be problems: class Foo(@JsonProperty private bar: String) The intent in this case is to ensure that the private field gets serialized. The JVM code generated in this corresponds to: class Foo {
private final String bar;
private Foo(@JsonProperty String bar) {
this.bar = bar;
}
} I get that automatically triggering visibility of the private field is more problematic here; if no name is specified it could make sense, but if a name is specified, then it's not clear from context whether I'm open to suggestions. I suppose the simplest solution is to not support this case, but I'd need a different lever to turn. The two options I can think of are
|
My main concern with private fields is that their use for access (instead of getters) really is something that violates expectations and leads to security issues by Java usage (and possibly Scala). One possibility would be adding yet one more The canonical usage block I am thinking of is something like: public class Credentials {
private String password;
@JsonCreator
public Credentials(@JsonProperty("password") String pw, ....) {
}
} where user would have write-only field. I am open to other ways of dealing with this, if it's possible to recognize case classes. |
@christophercurrie With bit more thinking, I wonder if the better way here would actually be for Scala module's annotation introspector to raise visibility of fields for case classes. Thing is, these classes have somewhat special requirements so it is probably better to treat them as special, instead of trying to make general POJO handling work to also cover them. Method to override would be |
Going back to the earlier idea, maybe adding
then that Field should be left as a getter. This could be relaxed, if necessary, to also add "visible getter" (for step (1)), but I think I'd want to start with more restrictive to avoid accidental exposure of private fields. This setting should default to |
Ok one more idea still. I hope to implement #813, which adds a way to enforce read-only/write-only/read-write behavior, which in turn can override visibility based rules. This is for supporting direct annotation of |
FWIW, #813 now implemented; |
I think remaining issues (which do exist, wrt problems with properly handling Creator properties to be available during property name merging) are covered by more explicit issues, so closing this one. |
This issue relates to FasterXML/jackson-module-scala#197.
In Scala, the normal syntax for declaring a class takes a simplified form:
This generates a JVM class that is similar to the following in Java
Where things get tricky is in specifying annotations on fields. To rename a property, for example, the natural syntax would look like:
But the JVM that results from this looks like the following Java equivalent:
The getter is not tagged with the new name, and so the renaming doesn't happen on serialization. Similar issues exist for other annotations or other uses of
@JsonProperty
(such as exposing private fields)The issue can be worked around in Scala by changing the way the annotation is specified on the class:
This example is deliberately extra verbose, because even though the annotation does not need to be present in all of those locations in all cases, figuring out which ones it's needed for is a pain for Scala users.
An alternate workaround would be to create type aliases in Scala that do the same thing:
This is slightly better for the end user, though still not ideal, and the set of annotations would need to be kept in sync with the databind library.
The ideal solution would be a way for the Scala module to signal to databind that the annotation for the constructor parameter is significant in other locations as well. Currently this is done using faking it in
findNameForSerialization
, but that's not a general solution.The text was updated successfully, but these errors were encountered: