Opening classes for frameworks #40
|
What I like in the "META-INF file" solution is that's:
We are ok to integrate such META-INF file directly in Spring Framework JAR. Instead of listing every single annotation like |
Could you clarify? What issues do you mean?
Isn't such file an example of custom configuration? |
I see your point, and it's very appealing. One problem: this brings the notion of "indirectly annotated" into the picture, and while it may be very obvious what that means for Spring, I'm not sure that it can be defined in a one-size-fits-all way. This speaks in favor of a compiler plugin where each framework could potentially define its own predicate using the full power of a programming language, not a restricted declarative format in |
|
One of my main concern is to make such behavior reliable and minimize the amount of customization for the end user. I would like to avoid issues like the default open class behavior is taken in account by the Gradle/Maven but not the IDE. META-INF file solution is maybe a kind of custom configuration but it would be taken in account by any Kotlin 1.1 based compiler without any custom configuration at build tool level. My remark about If the chosen solution is a compiler plugin, what would be the requirement for us? Some kind of |
Fair point, a pro for the static config file is that it can be read with equal ease by all tools. Effectively, all tools would inherit this functionality from the compiler. I'm not entirely convinced that adding such (arguably ad hoc) things to the compiler is generally a good course to take. |
This is an important refinement of the initial requirements, we should probably think a little more about it.
I'd imagine that it should be something like |
|
@abreslav Is that still expected to be available in Kotlin 1.1 ? |
|
btw, solution "META-INF file` also provides ability to specify nullable/not-nullable annotation types. Some frameworks (for example vert.x) use their own annotations so they can supply such meta-inf file for better Kotlin compatibility |
|
@abreslav Any estimation when we'll have this ..fixed''? I'd really like to apply shiny kotlin syntax to my projects. But it's a showstoppper for now as we are heavily using spring.. |
|
@sdeleuze @Writtscher We are currently working on a prototype with the following properties:
This plugin will be available from the command line, and in build scripts we are planning to have plugins that configure a particular framework with more or less a one-liner, like
If everything works out alright, this will ship in 1.0.x EAP soon enough (long before 1.1). We also plan to do the same for no-arg constructors for JPA and other serialization frameworks. I'll update the KEEPs accrodingly next week. |
|
That's awesome news @abreslav thanks a lot!!! |
|
Brilliant work, thanks a lot! |
|
Can I check if the proposed solution will work for tests run directly from IntelliJ? For instance for spring integration tests? As far as I know IntelliJ uses Kotlin compiler directly bypassing maven/gradle |
|
@pbartoszek According to https://blog.jetbrains.com/idea/2016/10/intellij-idea-2016-3-eap-refactorings-to-java-8-vcs-integration-and-gradle/ this won't be an issue in IDEA 2016.3 |
|
@pbartoszek The IDE will run everything correctly after importing the settings from Gradle (as it routinely does for dependencies) |
|
It looks like it's time to move from maven to Gradle :) |
|
@pbartoszek We are planning to have the same support for Maven as well |
|
Looking forward to the plugin as well... Definitely one of the reasons I've been holding off on trying kotlin for a spring project |
|
@abreslav For such classes can we have a Kotlin annotation or keyword like this? |
|
@oluwasayo There will be a generic plugin that uses the list of "all-open" annotations provided by the user, as well as some plugins for the popular frameworks (such as "kotlin-spring"). |
|
@yanex Awesome! |
|
Guys, do you have any update on plugin? |
|
@pbartoszek We are planning to release it as a part of Kotlin 1.0.6 in the middle of December. |
|
Any chance there will be an option to open all classes? |
|
@eygraber Why do you need this? |
|
@yanex If I want to mock a lot of classes, but I don't want to annotate each one of them. |
|
@eygraber - try mocking with Mockito 2.2 with mock-maker-inline enabled - works like a charm with closed by default Kotlin classes and methods. |
|
@angryziber it doesn't work on Android devices |
|
@eygraber Why don't make all mockable classes implement some interface with the all-open annotation on it? |
|
@yanex I have a large number of complex classes that I would need to mock, and I don't like the idea of adding an annotation (or interface) that exists only for testing. It's much easier to just say that for testing everything should be open. |
|
Isn't there an internal Kotlin-specific annotation that you could abuse for
this?
Kirill Rakhman
Am 27.12.2016 8:18 nachm. schrieb "Eliezer Graber" <[email protected]
…
|
|
The appropriate solution for allowing all classes to be mocked in tests is to use a custom JUnit test runner that removes the |
|
@yole again that would cause issues on Android because running tests on Android uses a custom runner. I tried creating an Android transform in a gradle Plugin a while back, but I wasn't able to get it to work well (no_more_finals_plugin). I'd say this issue on Android will most likely need to be addressed differently unless there's a method to remove final from all classes. |
|
Another issue with Android is that whatever is done needs to happen at compilation time before dexing, otherwise typical bytecode manipulation won't work (because it's dex not Java bytecode). |
Kotlin has classes and their members
finalby default. This has been causing debates that are summarized in this forum post. While all the reasoning behind this default remains valid, there are use cases that tend to be painful, most notable are frameworks using CGLib proxies (e.g. Spring AOP, Mockito) and Gradle that decorates task classes at runtime.We propose to enable a compilation strategy that does not classes and their members
finalif they are marked with framework-specific annotations, such as@Service,@Repository,@Bean,@Configuration.Open issues:
@Component)