2019.3 Beta Release RADICALLY Different from EAP versions
I just got a surprise with the Beta version of 2019.3.
I have been dutifully running tests on latest versions and all was going good. Until I got the Beta of the IDE.
First of all it comes with Kotlin 1.3.60 EAP, while EAP had 1.3.50. I have an old library written way back when Kotlin was still 1.0 and I was experimenting with what I can do with Kotlin. The library is a dog and is on the chopping block but I was planning to do this after the cleanup I am doing.
This library fails completely with 1.3.60. There is no salvaging it. I tried. I know it is my problem, but going from EAP to Beta with major changes that break what worked in previous releases and all EAPs seems to defeat the point of working with EAP releases since they do not reflect what's coming.
There are also a lot more stringent checks on what can be done during component initialization and this is causing failures of my plugin. Again, I know it is my problem and I cleaned that up, but it would be really nice to get a heads up with the EAP releases instead of finding out about when Beta rolls out.
I love the IDE and can't live without it but maintaining plugins for it is a PITA. I tried everything, using latest EAP versions, using daily snapshot builds to get a heads up of what to expect in the new release. And I still feel like the rug is pulled from under my feet as the release approaches.
Meanwhile, users think that I coded the plugin four years ago and now I am sitting on my behind, doing nothing but collecting license fees. ZZ-TOP lyrics come to mind: "money for nothing and chicks for free"
Please sign in to leave a comment.
Hello Vladimir,
Thanks for your report. I'd like to request the following information to better understand:
Could you please explain what kind of incompatibilities you experienced going from Kotlin 1.3.50 to 1.3.60?
There are also a lot more stringent checks on what can be done during component initialization and this is causing failures of my plugin.
Could you give some concrete examples, please?
Thanks!
Hi Yann,
Kotlin 1.30.60 differences: open method invocation during construction behaves differently than 1.30.50 and all prior versions. Specifically, from observation of code execution, where previously there was partial initialization of the derived class, now the derived class is not initialized until the super class is fully constructed. Calls to subclassed methods from super class constructor, get values in subclassed fields which are now consistently null where in previous versions they contained initialized values from partially constructed sub-class.
It is not a Kotlin problem. I prefer strict enforcement and consistency of the current version. Unfortunately, when I wrote the library, Kotlin was in diapers and figuring out initialization order was a trial and error experience. I was planning to ditch the library as soon as possible and was in the process of preparing for the replacement. Not a walk in the park because I wound up using some of the library's functionality for ALL text gathering, transformation and formatting. Yup, all over the place with implementation dependency on quirky behaviour of those classes, silently folded into the current code for added measure of fun.
This forced me to ditch it sooner than I was ready but necessity is the mother of invention.
More stringent checks: old code was causing the loading of the plugin's language SyntaxHighlighter in the plugin's initializeComponent() method. The latest version generates an exception complaining that the call should be made when state is initialized, instead the state is .... I already fixed the code so do not have the exact exception. The latter implementation was also in old Kotlin code that needed attention and it got that attention sooner than planned.
Kotlin 1.30.60 differences: There was an exception for access violations in my SyntaxHighlighterBase derived class, written in Kotlin. The exception complained that an attempt was made to access a protected method (of SyntaxHighlighterBase) from the companion object method (of the subclass extending the SyntaxHighlighterBase). I did not bother investigating what the issue was. I just implemented the simple method in my own class and went on to other issues.
My issue is not with making changes or improvements. I am all for it. My shock is that going through all EAP releases, Preview Releases and Release Candidates means nothing for compatibility with the next more stable release. I have seen breaking changes introduced between RCx releases. Which means that there is major s**t being changed in the implementation in late phases of the release cycle, Usually this would require bumping down the release candidate to at least Beta to allow time for downstream dependents (ie. plugin developers) to prepare for the incompatibility. Instead, the next RCx label gets slapped on the release and away it goes.
Effectively, I have no confidence of having a compatible plugin until the final release is made and I try it out.
Hi Vladimir,
I don't quite understand why differences between Kotlin versions caused problems for you. Note that there are 3 different versions of Kotlin which may affect plugin development:
1) version of kotlin-stdlib library bundled with IntelliJ platform. The current version is 1.3.31 and it wasn't changed since 2019.2. If you want to use a different (newer) version of kotlin-stdlib you can bundle it with your plugin and it'll be used instead the platform one.
2) version of Kotlin compiler which is used to compile the plugin's code. It is specified in plugin's build scripts and changes in IDE doesn't affect it. You can use any version of Kotlin compiler provided that it's compatible with version of kotlin-stdlib in your plugin.
3) version of Kotlin plugin bundled with IntelliJ IDEA. This version is different for different IDE builds (e.g. we're going to bundle 1.3.60 release of Kotlin with the final release of IntelliJ IDEA 2019.3 so it's natural that we started bundling EAPs of Kotlin plugin with pre-release builds of IntelliJ IDEA). Version of bundled Kotlin plugin may affect your plugin only if your plugin depends on Kotlin plugin and uses its API. Is it the case?
Nikolay, I have plugin failure caused by that infamous library written in Kotlin, only in 2019.3 Beta with Kotlin plugin 1.30.60.
No recompilation of the plugin. I tried the last released version of the plugin and it failed the same way as my dev environment. My plugin does not depend on the Kotlin plugin, only on the bundled Kotlin run-time since I stopped bundling Kotlin run time with the plugin when all IDEs started bundling it because my plugin does not rely on the latest Kotlin.
It sounds like I should put the Kotlin run-time back into the plugin distribution to stay safe. I will try that to see if it solves the problem for that version.
However, there is a difference in the compiler and run-time in 1.30.60 that breaks backward compatibility because when I patched the 2019.3 Beta with Kotlin plugin version 1.30.50 everything worked like before. No run-time failures. With 1.30.60 the library fails at run-time and will not compile. The latter is not a problem as far as I am concerned. Crap code should not compile.
The run-time however should not fail if it worked with previous versions, without major version changes to signal backward compatibility breaks.
Am I missing something on the backward compatibility part or does this library do something so alien that it breaks backward compatibility no one knew about?
Yann, here is the initialization exception. This time it is not in my plugin but in Database Tools plugin:
https://youtrack.jetbrains.com/issue/DBE-9449 Please report such errors in YouTrack, it will be easier to assign/monitor them, thanks.
Yann, I was not reporting an error. I was giving a concrete example of breaking changes from EAP to BEATA that even JetBrains produced plugins trip over.
Ok sorry, I misunderstood your intent then.
To make clear, not reporting a bug. I already sent a report with an explanation for it. This is for posterity to show that my use case was not really that alien because it is used in the IDE itself:
In the last few updates of intellij-community, the Git Log view tab is broken when diff view as editor tab option is selected and generates an NPE on mainFrame field being null. The latest fix attempted to fix it by making sure the mainFrame field is a newly created instance. Therefore NEVER null. However, this did not fix the NPE because it is caused by the "New Improved" Kotlin run-time behaviour for class field initialization, the same one that I pointed out which broke my old library.
The NPE on mainFrame field being null is caused by Kotlin 1.30.60+ runtime not initializing any class fields until the super classes are initialized.
The mainFrame field is not null in the constructor call, but the getOwner() method which uses this field is invoked during the super class constructor, at this point mainFrame field will be null because the sub-class is not initialized.
Glad to see I am not the only one that finds this new behaviour un-intuitive and unsupported by the language inspection tools. So when
it breaks common use cases for sub-classes to provide super class properties, you are on your own to figure out why the code fails in such an un-intuitive way.
Here is the stack trace for anyone interested:
Not having VCS Log available in the snapshot build for 3 days was long enough.
I added a patch to the issue I reported when intellij-community project update broke VCS Log view. https://youtrack.jetbrains.com/issue/IDEA-229187
In this case the fix was simple because there is only one super class with two inheritors. In my library the hierarchy is Pachinko code with calls to sub-class overridden methods done during super class construction everywhere.