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

Add jackson-kotlin-module in a Kotlin-based project when Jackson is present #462

Closed
sdeleuze opened this issue Jul 16, 2017 · 6 comments
Closed

Comments

@sdeleuze
Copy link
Contributor

As asked on #152 and as a follow-up of #400, I create a dedicated issue for discussing a way to add jackson-kotlin-module for Spring Boot + Kotlin + Jackson projects (mostly Web and Reactive Web projects) with a copy & paste of my #152 last comment.

I truly understand this is not an easy one, but even with documentation, projects using Boot + Kotlin + Jackson (vast majority of Kotlin projects) are broken out of the box for use cases as simple as writing a REST webservice. IMO even experienced developers will forget to add it 50% of the time because with start.spring.io, we have the habits of just generating a project, write classes, run and it works. So when I saw this issue I thought it would be interesting to discuss if it could be use to help for such use case (even if maybe it is not).

Having the capability to add a post-processor able to inspect transitive dependencies and add jackson-kotlin-module dependency when jackson-databind is found in transitive dependencies and when "language == 'kotlin'" would be awesome, but as you said that's not possible easily currently and that's not what I had in mind.

My proposal is a more basic approach where we leverage the new feature discussed here to add for dependencies like "Web" and "Reactive Web" (maybe a few others like "Ratpack" or "Vaadin" if that makes sense) an additional jackson-kotlin-module dependency if a condition like "language == 'kotlin'" is fulfilled. This is not a perfect solution (duplication in the meta-data, will not cover all use cases if we focused on the most common dependencies requiring Jackson) but given the current set of constraints, I thought it could be a possible one.

Any thoughts?

@snicoll
Copy link
Contributor

snicoll commented Jul 17, 2017

I agree this problem is serious and should be fixed. A concrete guide could be a very good start rather than looking immediately for automation (Do you have an ETA for the proposal you've made on #400?).

Spring Boot could also log a warning if we're able to detect the app is kotlin based and jackson is present and that module isn't.

IMO, start.spring.io must remain a convenience and not the source of the actual solution so I'd like we take a step back and see how we could solve the issue at a more fundamental level.

@sdeleuze
Copy link
Contributor Author

ETA for the guide is Spring Framework 5.0 GA, I plan to begin working on that asap RC3 is released (so next week) and I have already implemented such warning on Spring Framework side.

If the solution to get it working would imply some additional code configuration and push start.spring.io outside of what it does usually, I would agree that we maybe need to see how to solve in another way, take a step back, etc. But here, I don't think we are in front something that is outside start.spring.io scope of generating a project with the relevant set of dependencies to get it working out of the box.

4 things I can observe here are :

  • This is challenging to implement on start.spring.io because this kind of conditional dependency based on this language (and optionally the transitive dependencies) is not managed yet.
  • Kotlin typical code is heavily based on immutable DTOs which requires serialization/deserialization library to be aware of Kotlin metadata (parameter names, optional parameter with default value).
  • Jackson strategy is to have a dedicated module to have Kotlin support, this in line is what they do for language specific support.
  • Kotlin is already a good citizen in term of Java interoperability and do its best to call Java constructors/setters when possible, but typical use cases require to have Kotlin specific support, regular Java support is not enough.

So in the end, the requirement to have jackson-kotlin-module dependency to make Spring Boot + Kotlin + Jackson projects working makes sense IMO.

"I'd like we take a step back and see how we could solve the issue at a more fundamental level.

I am not sure what you mean by that, could you please elaborate?

@snicoll
Copy link
Contributor

snicoll commented Jul 19, 2017

I am not sure what you mean by that, could you please elaborate?

Certainly.

start.spring.io must remain a convenience. IMO, if Jackson can't fix it and you've added a warning on the framework side, the only thing that I can think of is a way to translate that exception in a smart way to tell the user that something is missing. I'd be much more in favour of us doing that than hiding the problem because start.spring.io does something behind the user's back.

I disagree that such fine tuned action should be declarative (which is why I think #152 is not the right call for that request). A quick spike to try to implement something that would do that should reveal if I am wrong though.

If we agree with this, then a RequestPostProcessor that inspects the project and does something smart can be envisioned. But because the project request won't state that jackson has been selected (there's no such option) we're entering a totally new territory. That's why I'd like that we evaluate other ways of fixing this problem.

@bclozel
Copy link
Member

bclozel commented Jul 19, 2017

If this issue is a such a serious one, solving it at the initializr level looks like a band-aid to me.

Spring Framework, Data, Boot, etc - all chose to provide Kotlin support out-of-the-box in the regular JARs. The Jackson community has a different approach (for now) and other libraries could do the same. So doing this might just be the start of many.

Which leads me to think: if we're that serious about Kotlin, shouldn't we add that 40Kb module to the Boot JSON starter and be done with it? We already have three of those: JDK8, parameter name, jsr310 (when you think of those, they should be a single module, right?).

Another solution would be to provide a Kotlin starter with various extensions - but this would not qualify as a starter per se.

@sdeleuze
Copy link
Contributor Author

@bclozel Good point, adding jackson-module-kotlin (with exclusion of koltin-reflect dependency) to spring-boot-starter-json as described in spring-projects/spring-boot#9803 would solve this issue on Springn Boot side, so that would be even better.

@snicoll snicoll changed the title Provide a way to add language specific dependencies Add jackson-kotlin-module in a Kotlin-based project when Jackson is present Jul 24, 2017
@snicoll
Copy link
Contributor

snicoll commented Jul 26, 2017

We've decided to add the dependency in Spring Boot's json starter.

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

No branches or pull requests

3 participants