jackson-module-scala icon indicating copy to clipboard operation
jackson-module-scala copied to clipboard

"get" appearing in property names with 2.6.x

Open wuservices opened this issue 10 years ago • 12 comments

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.

wuservices avatar Sep 15 '15 18:09 wuservices

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.

christophercurrie avatar Oct 14 '15 15:10 christophercurrie

@wuservices Can you tell me what I might have done wrong attempting to reproduce this? My test cases pass. See: https://github.com/FasterXML/jackson-module-scala/pull/237

nbauernfeind avatar Mar 01 '16 06:03 nbauernfeind

@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.

wuservices avatar Mar 01 '16 16:03 wuservices

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.

clintmiller1 avatar Sep 27 '16 15:09 clintmiller1

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

cowtowncoder avatar Sep 27 '16 20:09 cowtowncoder

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

a1russell avatar Oct 07 '16 18:10 a1russell

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}
}

keshin avatar Jul 20 '21 13:07 keshin

@keshin could you try upgrading to v2.12.x? https://github.com/FasterXML/jackson-module-scala/issues/455 might help you.

pjfanning avatar Jul 20 '21 14:07 pjfanning

@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

keshin avatar Jul 20 '21 15:07 keshin

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 avatar Jul 20 '21 16:07 pjfanning

@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

pjfanning avatar Sep 27 '21 22:09 pjfanning

@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.

keshin avatar Oct 08 '21 05:10 keshin