Skip to content
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

Synthetic Kotlin constructors confusing Jackson data binding #1005

Closed
apatrida opened this issue Nov 17, 2015 · 5 comments
Closed

Synthetic Kotlin constructors confusing Jackson data binding #1005

apatrida opened this issue Nov 17, 2015 · 5 comments
Milestone

Comments

@apatrida
Copy link
Member

Here is the full issue reported to Kotlin issue tracker:
https://youtrack.jetbrains.com/issue/KT-10049

It shows that there are cases when using default values that Kotlin creates a secondary constructor (synthetic access flags 0x1001) and copies over the JsonCreator annotation, but not JsonProperty annotations. Regardless, Jackson sees and tries to use this constructor.

Should Jackson be ignoring synthetic constructors?

See byte code in that issue above.

note: with the Jackson Kotlin module, this problem doesn't exist. But worried it will come up in evil ways later.

@cowtowncoder

@cowtowncoder
Copy link
Member

Yes, I think synthetic constructors should be skipped, unless proven it's necessary to detect and use them. Synthetic and bridge methods are ignored, I think.

Would there be an easy way to reproduce this, outside Kotlin?

@apatrida
Copy link
Member Author

Not that I can think of without using ASM to generate code. But I can put the failing test case in the Kotlin module test code so you can see it. If you have intellij with kotlin plugin (download v15 community if not) you can just debug it like normal Java. You won't die seeing a little Kotlin :-) It isn't dirty (like some languages) and is fully interoperable for visible things between java and Kotlin. I can add the test and mark as @ignore ... then you can unmark and right-click run the test

@apatrida
Copy link
Member Author

Ok, in the Jackson Kotlin Module, pull it (you likely have it already), then open it with IntelliJ 15 (community edition is fine). Update your Kotlin plugin to latest (it should prompt if it isn't already, but double check in plugin settings). 1.0.0-beta-2423 is latest and matches the project.

Then open the pom.xml of the project and that'll create your intellij project for you.

In the src/test/kotlin/com/fasterxml/jackson/module/kotlin/test folder right click on GithubDatabind1005Test and debug. You can easily go into class files of Jackson by searching for the class and telling IntelliJ to download the source for you. Then debug what/why. Error is thrown in BasicDeserializerFactory line 512.

You can also just add this one kotlin file to your normal jackson databind project within intellij, as long as you have the kotlin plugin installed it will work fine. Drop it into your tests dirs there. Nothing special needed outside the plugin.

@abreslav
Copy link

Here's how you get a synthetic constructor with pure Java:

public class Foo1 {
    static class C {
        private C() {}     
    }

    public static void main(String[] args) {
        new C();
    }
}

Byte code:

class Foo1$C {

  // compiled from: Foo1.java
  // access flags 0x8
  static INNERCLASS Foo1$C Foo1 C
  // access flags 0x1008
  static synthetic INNERCLASS Foo1$1 Foo1 null

  // access flags 0x2
  private <init>()V

  // access flags 0x1000
  synthetic <init>(LFoo1$1;)V
}

@cowtowncoder
Copy link
Member

@abreslav Awesome thank you! I hope to create a unit test soon to get this resolved for 2.6.4 / 2.7.0 -- right now very busy at work but should get it to this weekend.

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

3 participants