-
Notifications
You must be signed in to change notification settings - Fork 40.8k
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
Improve Kotlin support #5537
Comments
Gradle pluginOur plugin applies the Java plugin automatically. That doesn't make sense when you're building a pure Kotlin project and leads to unnecessary noise as the Java-related tasks are still run as part of the build:
|
/cc @jkschneider |
If looks like |
Spring MVCReified extension functions for the |
Spring HATEOASExtension functions to improve the transformation of objects and collections of objects into |
Thanks for creating this issue @philwebb 👍, I am especially interested by removing the need for the Maybe we could discuss Monday with the team if they would be ok to automatically register Kotlin Jackson module in @jkschneider Good idea about Spring HATEOAS. Be aware that I also plan to experiment on allowing to specify relations thanks to annotations + regular data classes, see spring-projects/spring-hateoas#401 for more details. Nothing specific to Kotlin, but that will make it easier to deal with data classes in both Kotlin and Java. |
@philwebb SPR-14108 + related pull request for Jackson Kotlin module automatic registration submitted for inclusion in Spring Framework 4.3. |
I have just merged Jackson Kotlin module automatic registration, so it will be available in About About extensions, Kotlin Primavera contains some examples of Kotlin extensions applied to Spring (I am sure there a lot of others to imagine even more useful). I have tried to reproduce the "Default constructor arguments with You can find bellow some issues from Kotlin bugtracker related to Spring:
|
@lkogler - Hadi Hariri mentioned you as a Spek contributor. Thought you might be interested in this effort as well. |
@sdeleuze Sent a PR for "Default constructor arguments with Thanks for putting together all of the links! @philwebb or @sdeleuze if you could create a spring-kotlin project in spring-projects and give me commit access, I'll start pouring in the work I have here. |
@jkschneider As a first step I have created the I already gave you the push rights, please sign the CLA as explained in the README. I will setup the build process using http://build.spring.io and publish the snapshots in https://repo.spring.io/snapshot/ as soon as we have the first bits committed. Does it sound ok for you? |
@sdeleuze He's signed the CLA for spring cloud previously. |
@sdeleuze thanks, sounds like a plan! |
I'm interested as well, and have just signed (again?) the CLA - just to be sure. |
Nice :-) |
@sdeleuze Regarding the default finality problem, what do you think about a Lombok-style annotation-processor hack to strip final from the bytecode at annotation-processing time? It isn't ideal in the sense that it requires a plugin (Eclipse) or non-default setting (IntelliJ), but... Otherwise, I'm not sure where we would put a custom ClassLoader such that all entry points would be covered (main, servlet initialization, test, etc.). |
Honestly I really would like to avoid using Lombok-style annotation-processor hack, since IMO one of the Kotlin advantages is to avoid this kind of non standard code that requires special support in IDEs and build tools. I would rather try to experiment with custom bean classloaders, reflection and eventually JDK dynamic proxies to see if we can do something here. Only Spring need to extend these classes for technical reasons, the end user code don't have to, so even if I am not a reflection guru, I think it is worth to try that way. |
@sdeleuze
|
Thinking aloud: I wonder if JetBrains would consider an enhancement to Kotlin that allows an annotation to make a class open, perhaps via a meta-annotation? |
@wilkinsona The question has been forwarded to the Kotlin team at JetBrains, I would be in favor of such solution. |
Thank you all in advance for pushing this stuff forward! |
@jkschneider I have merged your PR in kotlin-autowired-constructor to reproduce the issue you described , and indeed I got an error, but an That said, I am not sure this should be seen as a bug. For now, I think I would be in favor to just add some documentation about that behavior (in the additional tips section of my Kotlin + Spring Boot blog post for example). Any thoughts? |
See SPR-14165 about supporting Kotlin nullable information in Spring MVC. |
I have created an issue on Kotlin bugtracker to find a workaround to the annoying mandatory |
Is this really a problem? We've been developing Spring Boot applications on top of Kotlin for a couple of months and we've just adjusted :) Changing this behaviour right now, after 1.0.0 was released is not really a good idea. |
I think exposing such technical detail to the user is a real issue, at least for me. It gives a feeling that using Spring + Kotlin is not "natural" IMO. In any case, if we find a solution, it won't break your application, it will just make Spring + Kotlin working without |
@sdeleuze If you haven't already, you can read through the long discussion here on the Kotlin forums. Eventually, Andrey Breslav answered with a blog post on final-by-default that outlined why it is unlikely to change on their side. In spite of the great points he makes here, I think there is virtually no risk to opening classes and methods we know need to be open after an initial pass of the Kotlin compiler. In short, let the Kotlin compiler use final constraints to check smart casts, etc and then open whatever needs to be opened. Seems to be the best of both worlds. I think reflection and JDK dynamic proxies that you mentioned earlier are out, since reflection cannot affect finality (unlike visibility) and dynamic proxies only really apply to interfaces... but perhaps there is another solution here I am not imagining? Code generation or bytecode manipulation is going to have to happen, it's just a question of whether we get it done at compile time or runtime. Runtime: AFAIK, the Spring bean-creating mechanism does not use a custom classloader, so there is no opportunity there. Without looking deeper, it is unclear to me whether we have a hook after bean definition but before bean initialization (e.g. Compile-time: Since we have no compile-time metaprogramming facility yet, kapt was the only option. Since it only runs in Gradle and not in IntelliJ. It used to be the case that you could choose to debug/run things either with the IntelliJ platform or Gradle, but as of Idea circa 15, this only applies to test runners. I did write a more or less complete version of the annotation processor solution late last week before realizing that IntelliJ wouldn't pick it up. Shame, because the Eclipse case would have been covered by attaching a java agent to the JDT and we would have been home free. |
As discussed on Kotlin Slack, I have made some experiments about using As an alternative, I tried to update my Given the price to pay in term of IDE and build tool configuration (the kind of things I hate with lombok) for other solutions, that seems to be a good tradeoff IMO. For people still wanting to remove |
I think I should have been more explicit about what an annotation processor solution would NOT require. Lombok requires manual IDE config because the code it generates needs to be picked up by the IDE for code completion for other source code. The solution here only requires the bytecodes to be modified prior to execution, so would not require similar manual config. As far as the build tool goes, one or more of the Spring Gradle plugins could add the appropriate kapt dependency when necessary. |
The annotation processor is pretty transparent indeed and supported properly by the IDE but I wonder to which annotation it would be supposed to react. I haven't used kotlin much myself but it feels to me it is still a lot of setup to workaround a language decision... |
@snicoll I think the initial idea was to open classes annotated by @jkschneider Good point, indeed bytecode modification is only required for running the app, not compiling it. But I think we should be careful with such bytecode manipulation and limit the scope where it applies. For example, while that looks like an handy solution for simple apps, what would be the result of such bytecode modification in a multi-module application where you have your Based on my experiment and your last comment, maybe a good compromise would be to enable such bytecode modification only on Any thoughts? |
I have created a Spring + Kotlin FAQ : https://github.com/sdeleuze/spring-kotlin#spring--kotlin-faq @wilkinsona @philwebb Do you think we could do something to avoid the current CGLIB proxies by default behavior as soon as JDBC is used (see https://github.com/sdeleuze/spring-kotlin/blob/master/README.md#where-this-configuration-problem-configuration-class-foo-may-not-be-final-error-message-come-from)? |
I started working with Kotlin and Spring-boot for just one week, and the biggest pain point for me, not directly related to Spring-boot, but still, is Mockito. |
Good news, it seems Kotlin team is going to provide a solution to allow CGLIB proxies without having to open the class and all its functions. |
The long awaited solution to the I will update http://start.spring.io/ shortly. I am also in the process of integrating various Kotlin extensions directly in Spring Framework 5:
I have also a prototype of Kotlin based template rendering using Kotlin Script and Spring MVC |
You can use this link to track Kotlin related issues in the upcoming Spring Framework 5.0. |
@wilkinsona @bclozel It seems Spring Boot |
We won't go back implementing |
I think just providing a |
Following Spring Framework 5 Kotlin support announcement, and after a few weeks developing a real Spring Boot + Kotlin reactive web application, I have tried to summarise what features Spring Boot 2.0 could provide to improve Kotlin support:
|
Spring Boot 2.0 now provides following Kotlin features:
The only outstanding issue missing is IMO opinion #8762 the On start.spring.io side a lot of work has been done with @snicoll for Kotlin support:
The remaining outstanding issue needed before Spring Boot 2.0 release from my POV is the lack of After all the work done for Spring Boot 2.0, and given the fact that missing features have their own issues, maybe we should close this general purpose issue? |
Thanks for the summary @sdeleuze, I'll close this one. |
Placeholder issue for things we can do to improve Kotlin support
@value
Using
@Value("${thing}")
is a pain because you need to escape$
(e.g.@Value("\${thing}")
. Perhaps a different key like@Value("#{thing}")
.Open Classes
Open classes are a pain, can we use a classloader to remove
final
.Also all
@Bean
methodsperhaps we can use a custom bean classloader
Default constructor arguments with
@Autowired
Give a constructor with a default param:
Kotlin will create multiple constructors, this makes Spring fall over because there's multiple annotated constructors. A method to be smart about which to pick would be nice.
Main method
@JvmStatic
is needed for main methods. Check if we can find them automatically. Also the name of the class is a bit madThePackageKt
so perhaps we can replace it with something nice.Add Kotlin Module
Look at Jackson for an example.
The text was updated successfully, but these errors were encountered: