Skip to content

Getter is not detected correctly when method name is identical to variable name #202

@HoaBo

Description

@HoaBo
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ObjectWriter
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.junit.Test

class JsonSchemaTest {
  @Test
  def test(): Unit = {
    val mapper = new ObjectMapper
    mapper.registerModule(DefaultScalaModule)
    val generator = new JsonSchemaGenerator(mapper)
    val schema = generator.generateSchema(classOf[TestClass])

    val writer: ObjectWriter = mapper.writerWithDefaultPrettyPrinter().asInstanceOf[ObjectWriter]
    val schemaString = writer.writeValueAsString(schema)
    println(schemaString)
  }

  class TestClass {
    var firstName: String = ""
    var lastName: String = ""

    def firstName(firstName: String) { this.firstName = firstName }
    def lastName(lastName: String) { this.lastName = lastName }
  }
}

The result sometimes doesn't contain any properties, sometimes only contain firstName. I tried to debug and it is because the getter is not detected correctly because we have 2 methods with the same name

void lastName(String lastName) // generated from def lastName
String lastName() // generated from var lastName

The code to detect the getter

def findMethod(cls: Class[_], name: String): Option[Method] =
      listMethods(cls).filter(isNotSyntheticOrBridge).find(m => NameTransformer.decode(m.getName) == name).headOption
def findGetter(cls: Class[_], propertyName: String): Option[Method] = {
      findMethod(cls, propertyName).filter(isAcceptableGetter)    }

Unfortunately, findMethod returns the first one, which is refused to be a getter later by filter(isAcceptableGetter)

I fixed this by

def findMethodWithFilter(cls: Class[_], name: String, additionalFilter: Method => Boolean): Option[Method] =
      listMethods(cls).filter(isNotSyntheticOrBridge)
        .filter(additionalFilter)
        .find(m => NameTransformer.decode(m.getName) == name).headOption
def findGetter(cls: Class[_], propertyName: String): Option[Method] = {
      findMethodWithFilter(cls, propertyName, isAcceptableGetter)
    }

Please consider rolling this into master :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions