Skip to content

"get" appearing in property names with 2.6.x #224

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

Open
wuservices opened this issue Sep 15, 2015 · 12 comments
Open

"get" appearing in property names with 2.6.x #224

wuservices opened this issue Sep 15, 2015 · 12 comments

Comments

@wuservices
Copy link

Filed from discussion with @christophercurrie in #217.

Here's a possible pattern (not 100% sure). I think using @JsonProperty without a value is causing this. I've confirmed that the issue goes away when I don't register the Scala module.

I'm building JSON for a class named Product. @JsonAutoDetect is set up on Surface so nothing is autodetected so I have to whitelist properties with @JsonProperty.

@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE,
  fieldVisibility = JsonAutoDetect.Visibility.NONE,
  getterVisibility = JsonAutoDetect.Visibility.NONE,
  isGetterVisibility = JsonAutoDetect.Visibility.NONE,
  setterVisibility = JsonAutoDetect.Visibility.NONE)
public interface Surface { ... }

public abstract class AbstractSurface implements Surface { ... }

public class Product extends AbstractSurface implements Comparable<Product> { ... }

Some of my properties come from AbstractSurface and other come from Product, but I think that the ones that have the unexpected get prefix have @JsonProperty without a value.

Sorry, no test case right now but hopefully that points you in the right direction.

@christophercurrie
Copy link
Member

Thanks for the report. I have a good idea what might be causing it, but not sure how hard it will be to fix. I'll see what I can do.

nbauernfeind added a commit to nbauernfeind/jackson-module-scala that referenced this issue Mar 1, 2016
@nbauernfeind
Copy link
Member

@wuservices Can you tell me what I might have done wrong attempting to reproduce this? My test cases pass. See: #237

@wuservices
Copy link
Author

@nbauernfeind Thanks for trying to pinpoint this. For my similar structure, my member variables are protected in the middle class in the hierarchy (JavaAFieldVisibility) and private for the equivalent of JavaFieldVisibility. Also, I have getters for each member and I put @JsonProperty on the getters. Hopefully adding getters will be enough to repro the issue and if not, maybe visibility will change behavior too.

@clintmiller1
Copy link

clintmiller1 commented Sep 27, 2016

Is there any update on this issue? I've inherited a large code base that's filled with Java beans being serialized into JSON using Jackson. These beans are filled with @JsonProperty annotations that have no values. I'm trying to introduce Scala into the code base, but am being held up by this issue.

Here's an example of the problem:

public class Point {
        @JsonProperty
        private Integer x;

        @JsonProperty
        private Integer y;

        @JsonProperty
        public Integer getX() {
            return x;
        }

        @JsonProperty
        public void setX(Integer x) {
            this.x = x;
        }

        @JsonProperty
        public Integer getY() {
            return y;
        }

        @JsonProperty
        public void setY(Integer y) {
            this.y = y;
        }
    }

When I write this out using an ObjectMapper that has DefaultScalaModule registered on it, the resulting JSON is

{"x":5,"y":6,"getX":5,"getY":6}

If I don't register DefaultScalaModule, the resulting JSON is

{"x":5,"y":6}

The fix is in BeanIntrospector.scala. If you look at the following line near the bottom of the file

setter = findSetter(cls, name) if setter.isDefined || getter.getAnnotation(classOf[JsonProperty]) != null

I think you need to not just check if the annotation isn't null but also check to make sure it's value isn't an empty string. When I make that change locally, everything works correctly.

I'm on version 2.7.7 of the jackson scala module. I'm locked into 2.7 of the Jackson stuff because of dropwizard 1.0.

@cowtowncoder
Copy link
Member

@nbauernfeind Do you think suggested fix makes sense? Could perhaps make it in 2.7.8, before it gets released.

@a1russell
Copy link

I'm using 2.8.2 and seeing this issue, as well.

nicktelford added a commit to nicktelford/jackson-module-scala that referenced this issue May 18, 2017
When using `@JsonProperty` on a bean property (i.e. a field with
accessor methods), if you do not specify an explicit name for the
property, the `ScalaAnnotationIntrospector` was incorrectly generating
properties for the accessor methods.

In the following example:

```
class Bean {
  private var value: Int = 0

  @JsonProperty
  def getValue: Int = value

  @JsonProperty
  def setValue(value: Int): Unit = { this.value = value }
}
```

A mapper configured with the `ScalaAnnotationIntrospector` would
serialize this to:

```
{"value":0,"getValue":0}
```

This most notably impacts interop with Java-defined classes, as they
often follow the pattern of Java Beans, where the accessor methods are
annotated with `@JsonProperty`.

Credit for the fix goes to @clintmiller1
(FasterXML#224 (comment)).

I've included a test that verifies the problem, and the solution.
mbknor added a commit that referenced this issue Mar 28, 2018
@keshin
Copy link

keshin commented Jul 20, 2021

we're using 2.11.4 and seeing this issue as well with a java class only has @JsonProperty on getter. Unfortunately it's a provided class that we can't change.

A test case below can reproduce this issue:

class JacksonTest extends FunSuite {
  test("Jackson") {

    val mapper = new ObjectMapper()
    mapper.findAndRegisterModules() // remove this to not register the scala modules can pass the test
    val json = """{"v": 1}""".stripMargin
    val token = mapper.readValue(json, classOf[Sample1])
    assert(token.getValue == 1)
  }
}

@JsonIgnoreProperties(ignoreUnknown = true)
class Sample1 {
  private var value: Int = 0

  @JsonProperty("v") def getValue: Int = value
  def setValue(value: Int): Unit  = {this.value = value}
}

@pjfanning
Copy link
Member

@keshin could you try upgrading to v2.12.x? #455 might help you.

@keshin
Copy link

keshin commented Jul 20, 2021

@pjfanning , thanks, does 2.12.X compatible with jackson-core 2.11.X? it might be challenge for us to upgrade all version to 2.12.X for jackson, want to see if I can upgrade scala module only

We're on spring boot 2.4.6, where the managed version for jackson is 2.11.4

@pjfanning
Copy link
Member

pjfanning commented Jul 20, 2021

no - jackson-module-scala is designed to be used with jackson core of the same version - looks like spring boot 2.5.2 uses jackson 2.12.3

@pjfanning
Copy link
Member

@keshin your use case works if you move the @JsonProperty("v") to the setValue - you have to be aware that deserialization means that you need to set the values.

This also works

@JsonProperty("v") private var value: Int = 0

@keshin
Copy link

keshin commented Oct 8, 2021

@pjfanning, it's a provided class, I agree it's not a good one but I can't change it.
I tried to upgrade all jackson to 2.12.3 for my app (running with spring boot 2.4.6), everything looks good so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants