Document API Changes between releases of the IntelliJ Platform
Answered
Whenever you put out a new minor release of Idea, there are typically API changes in classes that my plugin depends on. My plugin then fails to compile in a bunch of places, and it is tedious to try to guess what changed and how to use the new API.
Can you please supply us with a complete set of API changes for each release, with an explanation of what changed, and how to adapt our code so it continues to compile and work?
There seems to be a document you put out with API changes, but it is not exhaustive. It looks to us as though things are added to that document as plugin writers discover them.
At the moment, we are dealing with 2019.2 to 2019.3.
Please sign in to leave a comment.
An example API that changed: org.jetbrains.jps.cmdline.ProjectDescriptor (the constructor).
I can second the motion but realize that it is difficult to ensure without some automation to enforce it.
I would settle for having a @since java doc annotation for newly added or changed APIs with a minimum build number for its appearance
@Deprecated annotations are good but I cannot update my API use until the oldest supported IDE version is the one with the new API implementation and there is an alternative API available to implement the same functionality.
it would also be a good policy to not mark an interface/class/method @Deprecated until all the APIs that mandate its use have alternative methods for the replacement. Example: com.intellij.util.Producer is deprecated in favour of Supplier but EditorTextInsertHandler interface only has one method and it uses Producer. This deprecation is kind of pointless and generates distracting compiler warnings.
More information in the code on the min build when the change was implemented would help a lot. Right now it is a tedious search through annotations to figure out when the new API came to be and what min build is required to use it.
Sometimes the changes are in Util classes and if there is too much code depending on it on my side, the only easy solution for backward compatibility is to copy the old version into my own code until I can migrate to the new API.
Overall, this upkeep activity is time consuming and I dread doing it for major and sometimes minor IDE releases.
Don't get me wrong. I love the improvements in the IDE. I just hate the extra work it generates for me on the plugin maintenance side.
Several points to add:
BGoldberg and Vladimir, Thanks a lot for your feedback.
Regarding "org.jetbrains.jps.cmdline.ProjectDescriptor (the constructor)" - it will be fixed.
Regarding "com.intellij.util.Producer is deprecated in favour of Supplier but EditorTextInsertHandler interface only has one method and it uses Producer" - fixed.
Regarding documentation of API Changes: you're probably referring to http://www.jetbrains.org/intellij/sdk/docs/reference_guide/api_changes_list.html and http://www.jetbrains.org/intellij/sdk/docs/reference_guide/api_notable/api_notable.html. These are indeed not exhaustive in the sense we do not list every single signature change of IntelliJ Platform and bundled plugins. Is that what you are looking for, something like a full diff?
We do use tooling in our development process as well as on the plugin repository to catch binary incompatibilies (https://blog.jetbrains.com/platform/2018/07/plugins-repository-now-integrates-with-the-plugin-verification-tool/). If your plugin is _not_ published on our plugin repository, please use https://github.com/JetBrains/intellij-plugin-verifier to verify compatibility locally.
We strive to have documentation for deprecated API explaining the reasoning/alternatives, if there are missing/unclear places please feel free to ping me on the Marketplace Slack or file a bug.
If you find any breaking or confusing changes in our API, please reach out to us ASAP so we can fix/document them early in the EAP cycle, thanks in advance.
Yann,
We don't want to limit code improvements or changes you guys make. We just want to be able to figure out reasonably quickly how to adjust our code for the changes and if they are major have a bit of a heads up warning it is coming.
I am sure you guys have tooling to help. Any chance the tool(s) keep track of binary incompatibilities caused by changes in the API from build to build?
I know tracking API changes is a daunting task. I personally would not want a telephone book printout of all changes. Instead what I would like is a fairly quick answer as to what build or version of the IDE the changes were made for a particular API method or class. If the change is major, a brief pointer where to look for implementing equivalent functionality.
I wind up doing this search using annotations and show vcs history up to revision. Which is great, but may require some effort to figure out when exactly the change was made. At which point I have a date of the change but no idea which build it was merged into, unless I search up in git history looking for a tag. I even considered writing a plugin to help me do it.
It would also help to know of major upcoming changes in earlier phases. Many times, including latest Beta, breaking changes went into Beta or RC releases with no hint of these changes in the EAP releases.
I was under the mistaken impression that later releases stabilize and fix bugs, with major shifts in the API or the way it functions to be seen in the EAP releases. I am giving up on that illusion and taking on the attitude that when you guys make a released I will figure what it breaks in my plugin then fix it when I can.
I love your products. They are the best IDEs I have used and I refuse to work without them. I wish we can figure out how to translate this amazing user experience into a similar experience as an active plugin developer.
Hi Yann,
Could the plugin verifier be adapted to help with this? The plugin verifier (as the name suggests) is for checking plugins, but what's really needed for these problems is something for the IDE itself.
It seems like this is something that might not be too hard - basically between the binary class files of two versions of the IDE, provide a list of the function signatures that have changed. I suspect a list of all those function signature changes would not be too large, especially if you remove the additive (i.e. non-breaking) changes from the list. It should then be possible to (either manually or automatically) check that each change has some doc explaining how to adapt to the change.
Of course, this wouldn't catch cases where the API is the same but the semantics have changed. My recent example of this was https://youtrack.jetbrains.com/issue/IDEA-225412. Here the existing API was maintained and marked deprecated, but it stopped working. Additionally, the deprecation notice indicated a solution that is not what clients of the API within IntelliJ itself used. And on top of all that the new API is marked experimental, so I have a choice of receiving warnings about using a deprecated API or warnings about using an experimental one.
However, the big problem I still see is that the verifier merely tells me what is wrong, and doesn't document what I need to do to fix it, or why the semantics/API changed. What my company does for our APIs to solve this problem is to maintain an API Diffs File, shipped along with the product, and referenced by API verifier. If the API verifier discovers a change for which there is no entry in the API Diffs File, it reports that problem so that an entry can be made. The API Diffs File then becomes the basis of user documentation. The API Diffs File is shipped along with the product, along with the plugin-verifier, so that a meaningful report can be produced by the plugin-verifier.
Can you do something similar?
Below, please see the results of running your intellij-plugin-verfier on one of our plugins (for Gosu), and how it doesn't tell us how to fix the problem, only that there is a problem. The remaining work of fixing the problems is tedious and time consuming. If the verifier were to look in the API Diffs File proposed above, it could then explain (for each problem) what changed and how to fix it.
----------------- output ----------------
Verification reports directory: verification-2019-11-11 at 16.29.20
2019-11-11T16:29:20 [main] INFO verification - Reading IDE /Applications/IntelliJ IDEA 2019.3 CE EAP.app/Contents
2019-11-11T16:29:22 [main] INFO verification - Reading plugin to check from ./ij-gosu
2019-11-11T16:29:22 [main] INFO verification - Task check-plugin parameters:
JDK : /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
IDEs : [IC-193.4932.9]
Plugins (1): [gw.gosu.ij:h-latest-user-rberlin-ISSTUDIO-527-SNAPSHOT]
Ignored : []
2019-11-11T16:29:29 [main] INFO verification - Finished 1 of 1 verifications: IC-193.4932.9 against gw.gosu.ij:h-latest-user-rberlin-ISSTUDIO-527-SNAPSHOT: Found 43 compatibility problems
2019-11-11T16:29:29 [main] INFO c.j.p.repository.cache.ResourceCache - Closing the JDKCache
2019-11-11T16:29:29 [main] INFO c.j.p.repository.cache.ResourceCache - Closing the PluginDetailsCache
Against IC-193.4932.9 the plugin gw.gosu.ij:h-latest-user-rberlin-ISSTUDIO-527-SNAPSHOT has 43 problems
#Invocation of unresolved method com.intellij.psi.statistics.StatisticsInfo.incUseCount() : void
Method gw.gosu.ij.psi.statistics.GosuStatisticsManager.incVariableNameUseCount(java.lang.String name, com.intellij.psi.codeStyle.VariableKind variableKind, java.lang.String propertyName, gw.gosu.ij.psi.GosuPsiType type) : void contains an *invokevirtual* instruction referencing an unresolved method com.intellij.psi.statistics.StatisticsInfo.incUseCount() : void. This can lead to **NoSuchMethodError** exception at runtime.
#Illegal access to package-private class com.intellij.util.containers.ConcurrentWeakHashMap
Package-private class com.intellij.util.containers.ConcurrentWeakHashMap is not available at gw.gosu.ij.psi.infos.GosuMethodCandidateInfo.inferTypeArguments(GosuParameterTypeInferencePolicy project, GosuPsiExpression[] gosuPsiFacade, boolean containingClass) : GosuPsiSubstitutor. This can lead to **IllegalAccessError** exception at runtime.
Package-private class com.intellij.util.containers.ConcurrentWeakHashMap is not available at gw.gosu.ij.codeInsight.daemon.impl.quickfix.CreateConstructorParameterFromFieldFix.getFieldsToFix() : Collection. This can lead to **IllegalAccessError** exception at runtime.
Package-private class com.intellij.util.containers.ConcurrentWeakHashMap is not available at gw.gosu.ij.codeInsight.daemon.impl.quickfix.VariableAccessFromInnerClassFix.getVariablesToFix() : Collection. This can lead to **IllegalAccessError** exception at runtime.
Package-private class com.intellij.util.containers.ConcurrentWeakHashMap is not available at gw.gosu.ij.psi.controlFlow.GosuControlFlowFactory.<init>(PsiManagerEx psiManager). This can lead to **IllegalAccessError** exception at runtime.
#Invocation of unresolved method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.SubclassUpdater.getTheOnlyOneElement() : PsiElement
Method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.SubclassUpdater.onFinished() : void contains an *invokevirtual* instruction referencing an unresolved method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.SubclassUpdater.getTheOnlyOneElement() : com.intellij.psi.PsiElement. This can lead to **NoSuchMethodError** exception at runtime.
The method might have been declared in the super classes or in the super interfaces:
com.intellij.codeInsight.navigation.BackgroundUpdaterTask
com.intellij.codeInsight.navigation.BackgroundUpdaterTaskBase
com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
com.intellij.openapi.progress.Task
com.intellij.openapi.progress.Task.Backgroundable
com.intellij.openapi.progress.PerformInBackgroundOption
com.intellij.openapi.progress.Progressive
com.intellij.openapi.progress.TaskInfo
#Illegal invocation of private constructor com.intellij.util.containers.ConcurrentFactoryMap.<init>()
Constructor gw.gosu.ij.codeInsight.GosuAnnotationUtil$3.<init>(GosuPsiModifierListOwner) contains an *invokespecial* instruction referencing a private constructor com.intellij.util.containers.ConcurrentFactoryMap.<init>() inaccessible to a class gw.gosu.ij.codeInsight.GosuAnnotationUtil$3. This can lead to **IllegalAccessError** exception at runtime.
Constructor gw.gosu.ij.codeInsight.GosuAnnotationUtil$1.<init>(GosuPsiModifierListOwner) contains an *invokespecial* instruction referencing a private constructor com.intellij.util.containers.ConcurrentFactoryMap.<init>() inaccessible to a class gw.gosu.ij.codeInsight.GosuAnnotationUtil$1. This can lead to **IllegalAccessError** exception at runtime.
Constructor gw.gosu.ij.codeInsight.GosuAnnotationUtil$2.<init>(GosuPsiModifierListOwner) contains an *invokespecial* instruction referencing a private constructor com.intellij.util.containers.ConcurrentFactoryMap.<init>() inaccessible to a class gw.gosu.ij.codeInsight.GosuAnnotationUtil$2. This can lead to **IllegalAccessError** exception at runtime.
#Illegal invocation of package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>(int initialCapacity)
Method gw.gosu.ij.codeInsight.daemon.impl.quickfix.CreateConstructorParameterFromFieldFix.getFieldsToFix() : Collection contains an *invokespecial* instruction referencing com.intellij.util.containers.ConcurrentWeakHashMap.<init>(int) which is resolved to a package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>(int) inaccessible to a class gw.gosu.ij.codeInsight.daemon.impl.quickfix.CreateConstructorParameterFromFieldFix. This can lead to **IllegalAccessError** exception at runtime.
Method gw.gosu.ij.codeInsight.daemon.impl.quickfix.VariableAccessFromInnerClassFix.getVariablesToFix() : Collection contains an *invokespecial* instruction referencing com.intellij.util.containers.ConcurrentWeakHashMap.<init>(int) which is resolved to a package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>(int) inaccessible to a class gw.gosu.ij.codeInsight.daemon.impl.quickfix.VariableAccessFromInnerClassFix. This can lead to **IllegalAccessError** exception at runtime.
#Invocation of unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>()
Constructor gw.gosu.ij.psi.controlFlow.GosuControlFlowFactory.<init>(com.intellij.psi.impl.PsiManagerEx psiManager) contains an *invokespecial* instruction referencing an unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>(). This can lead to **NoSuchMethodError** exception at runtime.
Method gw.gosu.ij.psi.infos.GosuMethodCandidateInfo.inferTypeArguments(gw.gosu.ij.psi.impl.source.resolve.GosuParameterTypeInferencePolicy project, gw.gosu.ij.psi.GosuPsiExpression[] gosuPsiFacade, boolean containingClass) : gw.gosu.ij.psi.GosuPsiSubstitutor contains an *invokespecial* instruction referencing an unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>(). This can lead to **NoSuchMethodError** exception at runtime.
#Access to unresolved field com.intellij.codeInsight.daemon.impl.HighlightInfoType.ANNOTATION_ATTRIBUTE_NAME : HighlightInfoType
Method gw.gosu.ij.codeInsight.daemon.impl.analysis.GosuHighlightVisitorImpl.visitNameValuePair(gw.gosu.ij.psi.GosuPsiNameValuePair this) : void contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.daemon.impl.HighlightInfoType.ANNOTATION_ATTRIBUTE_NAME : com.intellij.codeInsight.daemon.impl.HighlightInfoType. This can lead to **NoSuchFieldError** exception at runtime.
#Invocation of unresolved method com.intellij.codeInspection.magicConstant.MagicCompletionContributor.getAllowedValues(PsiElement) : MagicConstantInspection.AllowedValues
Method gw.gosu.ij.psi.filters.getters.GosuMembersGetter.addMembers(boolean searchInheritors, com.intellij.util.Consumer results) : void contains an *invokestatic* instruction referencing an unresolved method com.intellij.codeInspection.magicConstant.MagicCompletionContributor.getAllowedValues(com.intellij.psi.PsiElement) : com.intellij.codeInspection.magicConstant.MagicConstantInspection.AllowedValues. This can lead to **NoSuchMethodError** exception at runtime.
The method might have been declared in the super class: com.intellij.codeInsight.completion.CompletionContributor
#Invocation of unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>(int)
Method gw.gosu.ij.codeInsight.daemon.impl.quickfix.CreateConstructorParameterFromFieldFix.getFieldsToFix() : java.util.Collection contains an *invokespecial* instruction referencing an unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>(int). This can lead to **NoSuchMethodError** exception at runtime.
Method gw.gosu.ij.codeInsight.daemon.impl.quickfix.VariableAccessFromInnerClassFix.getVariablesToFix() : java.util.Collection contains an *invokespecial* instruction referencing an unresolved constructor com.intellij.util.containers.ConcurrentWeakHashMap.<init>(int). This can lead to **NoSuchMethodError** exception at runtime.
#Illegal invocation of package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>()
Constructor gw.gosu.ij.psi.controlFlow.GosuControlFlowFactory.<init>(PsiManagerEx) contains an *invokespecial* instruction referencing com.intellij.util.containers.ConcurrentWeakHashMap.<init>() which is resolved to a package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>() inaccessible to a class gw.gosu.ij.psi.controlFlow.GosuControlFlowFactory. This can lead to **IllegalAccessError** exception at runtime.
Method gw.gosu.ij.psi.infos.GosuMethodCandidateInfo.inferTypeArguments(GosuParameterTypeInferencePolicy, GosuPsiExpression[], boolean) : GosuPsiSubstitutor contains an *invokespecial* instruction referencing com.intellij.util.containers.ConcurrentWeakHashMap.<init>() which is resolved to a package-private constructor com.intellij.util.containers.ConcurrentRefHashMap.<init>() inaccessible to a class gw.gosu.ij.psi.infos.GosuMethodCandidateInfo. This can lead to **IllegalAccessError** exception at runtime.
#Access to unresolved class com.intellij.psi.impl.PsiTreeChangePreprocessorBase
Method gw.gosu.ij.psi.impl.GosuCodeBlockModificationListener.isOutOfCodeBlock(PsiFileSystemItem file) : boolean references an unresolved class com.intellij.psi.impl.PsiTreeChangePreprocessorBase. This can lead to **NoSuchClassError** exception at runtime.
Constructor gw.gosu.ij.psi.impl.GosuCodeBlockModificationListener.<init>(PsiManager psiManager) references an unresolved class com.intellij.psi.impl.PsiTreeChangePreprocessorBase. This can lead to **NoSuchClassError** exception at runtime.
Method gw.gosu.ij.psi.impl.GosuCodeBlockModificationListener.onTreeChanged(PsiTreeChangeEventImpl this) : void references an unresolved class com.intellij.psi.impl.PsiTreeChangePreprocessorBase. This can lead to **NoSuchClassError** exception at runtime.
Class gw.gosu.ij.psi.impl.GosuCodeBlockModificationListener references an unresolved class com.intellij.psi.impl.PsiTreeChangePreprocessorBase. This can lead to **NoSuchClassError** exception at runtime.
#Invocation of unresolved method com.intellij.psi.statistics.StatisticsInfo.getUseCount() : int
Method gw.gosu.ij.psi.statistics.GosuStatisticsManager.getVariableNameUseCount(java.lang.String name, com.intellij.psi.codeStyle.VariableKind variableKind, java.lang.String propertyName, gw.gosu.ij.psi.GosuPsiType type) : int contains an *invokevirtual* instruction referencing an unresolved method com.intellij.psi.statistics.StatisticsInfo.getUseCount() : int. This can lead to **NoSuchMethodError** exception at runtime.
Method gw.gosu.ij.codeInsight.daemon.impl.quickfix.GosuCreateFromUsageUtils.compareMembers(gw.gosu.ij.psi.GosuPsiMember m1, gw.gosu.ij.psi.GosuPsiMember m2, gw.gosu.ij.psi.GosuPsiExpression context) : int contains an *invokevirtual* instruction referencing an unresolved method com.intellij.psi.statistics.StatisticsInfo.getUseCount() : int. This can lead to **NoSuchMethodError** exception at runtime.
#Access to unresolved field com.intellij.codeInsight.TailType.COMMA : TailType
Method gw.gosu.ij.codeInsight.completion.GosuTypeArgumentCompletionProvider.getTail(boolean last) : com.intellij.codeInsight.TailType contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.TailType.COMMA : com.intellij.codeInsight.TailType. This can lead to **NoSuchFieldError** exception at runtime.
Method gw.gosu.ij.codeInsight.lookup.GosuVariableLookupItem.handleInsert(com.intellij.codeInsight.completion.InsertionContext ref) : void contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.TailType.COMMA : com.intellij.codeInsight.TailType. This can lead to **NoSuchFieldError** exception at runtime.
Method gw.gosu.ij.codeInsight.GosuExpectedTypesProvider.MyParentVisitor.getMethodArgumentTailType(gw.gosu.ij.psi.GosuPsiExpression call, int returnType, gw.gosu.ij.psi.GosuPsiMethod argument, gw.gosu.ij.psi.GosuPsiSubstitutor index, gw.gosu.ij.psi.GosuPsiParameter[] method) : com.intellij.codeInsight.TailType contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.TailType.COMMA : com.intellij.codeInsight.TailType. This can lead to **NoSuchFieldError** exception at runtime.
Method gw.gosu.ij.codeInsight.completion.GosuDefaultInsertHandler.getTailType(char completionChar, com.intellij.codeInsight.lookup.LookupItem item) : com.intellij.codeInsight.TailType contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.TailType.COMMA : com.intellij.codeInsight.TailType. This can lead to **NoSuchFieldError** exception at runtime.
#Invocation of unresolved constructor org.jetbrains.jps.incremental.storage.BuildDataManager.<init>(BuildDataPaths, BuildTargetsState, boolean)
Method gw.gosu.ij.testframework.compiler.JpsBuildTestCase.createProjectDescriptor(org.jetbrains.jps.builders.logging.BuildLoggingManager index) : org.jetbrains.jps.cmdline.ProjectDescriptor contains an *invokespecial* instruction referencing an unresolved constructor org.jetbrains.jps.incremental.storage.BuildDataManager.<init>(org.jetbrains.jps.builders.storage.BuildDataPaths, org.jetbrains.jps.incremental.storage.BuildTargetsState, boolean). This can lead to **NoSuchMethodError** exception at runtime.
#Invocation of unresolved constructor org.jetbrains.jps.cmdline.ProjectDescriptor.<init>(JpsModel, BuildFSState, ProjectTimestamps, BuildDataManager, BuildLoggingManager, ModuleExcludeIndex, BuildTargetsState, BuildTargetIndex, BuildRootIndex, IgnoredFileIndex)
Method gw.gosu.ij.testframework.compiler.JpsBuildTestCase.createProjectDescriptor(org.jetbrains.jps.builders.logging.BuildLoggingManager index) : org.jetbrains.jps.cmdline.ProjectDescriptor contains an *invokespecial* instruction referencing an unresolved constructor org.jetbrains.jps.cmdline.ProjectDescriptor.<init>(org.jetbrains.jps.model.JpsModel, org.jetbrains.jps.incremental.fs.BuildFSState, org.jetbrains.jps.incremental.storage.ProjectTimestamps, org.jetbrains.jps.incremental.storage.BuildDataManager, org.jetbrains.jps.builders.logging.BuildLoggingManager, org.jetbrains.jps.indices.ModuleExcludeIndex, org.jetbrains.jps.incremental.storage.BuildTargetsState, org.jetbrains.jps.builders.BuildTargetIndex, org.jetbrains.jps.builders.BuildRootIndex, org.jetbrains.jps.indices.IgnoredFileIndex). This can lead to **NoSuchMethodError** exception at runtime.
#Invocation of unresolved constructor org.jetbrains.jps.incremental.storage.ProjectTimestamps.<init>(File, BuildTargetsState)
Method gw.gosu.ij.testframework.compiler.JpsBuildTestCase.createProjectDescriptor(org.jetbrains.jps.builders.logging.BuildLoggingManager index) : org.jetbrains.jps.cmdline.ProjectDescriptor contains an *invokespecial* instruction referencing an unresolved constructor org.jetbrains.jps.incremental.storage.ProjectTimestamps.<init>(java.io.File, org.jetbrains.jps.incremental.storage.BuildTargetsState). This can lead to **NoSuchMethodError** exception at runtime.
#Invocation of unresolved method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.OverridingMethodsUpdater.getTheOnlyOneElement() : PsiElement
Method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.OverridingMethodsUpdater.onFinished() : void contains an *invokevirtual* instruction referencing an unresolved method gw.gosu.ij.codeInsight.daemon.impl.GosuMarkerType.OverridingMethodsUpdater.getTheOnlyOneElement() : com.intellij.psi.PsiElement. This can lead to **NoSuchMethodError** exception at runtime.
The method might have been declared in the super classes or in the super interfaces:
com.intellij.codeInsight.navigation.BackgroundUpdaterTask
com.intellij.codeInsight.navigation.BackgroundUpdaterTaskBase
com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
com.intellij.openapi.progress.Task
com.intellij.openapi.progress.Task.Backgroundable
com.intellij.openapi.progress.PerformInBackgroundOption
com.intellij.openapi.progress.Progressive
com.intellij.openapi.progress.TaskInfo
#Invocation of unresolved method com.intellij.psi.impl.search.PsiSearchHelperImpl.processTextOccurrences(PsiElement, String, GlobalSearchScope, Processor, UsageInfoFactory) : boolean
Method gw.gosu.ij.find.findUsages.FindUsagesHelper.processUsagesInText(com.intellij.psi.PsiElement s, java.util.Collection element, com.intellij.psi.search.GlobalSearchScope stringToSearch, com.intellij.util.Processor searchScope) : boolean contains an *invokestatic* instruction referencing an unresolved method com.intellij.psi.impl.search.PsiSearchHelperImpl.processTextOccurrences(com.intellij.psi.PsiElement, java.lang.String, com.intellij.psi.search.GlobalSearchScope, com.intellij.util.Processor, com.intellij.usageView.UsageInfoFactory) : boolean. This can lead to **NoSuchMethodError** exception at runtime.
The method might have been declared in the super interface: com.intellij.psi.search.PsiSearchHelper
#Illegal access to package-private class com.intellij.util.containers.WeakKeyWeakValueHashMap
Package-private class com.intellij.util.containers.WeakKeyWeakValueHashMap is not available at gw.gosu.ij.codeInsight.GosuBaseExternalAnnotationsManager.<init>(PsiManager psiManager). This can lead to **IllegalAccessError** exception at runtime.
#Access to unresolved class com.intellij.psi.SdkResolveScopeProvider
Method gw.gosu.ij.psi.impl.source.GosuAndJavaSourceFilterScope.contains(VirtualFile provider) : boolean references an unresolved class com.intellij.psi.SdkResolveScopeProvider. This can lead to **NoSuchClassError** exception at runtime.
#Illegal invocation of package-private constructor com.intellij.util.containers.WeakKeyWeakValueHashMap.<init>()
Constructor gw.gosu.ij.codeInsight.GosuBaseExternalAnnotationsManager.<init>(PsiManager) contains an *invokespecial* instruction referencing a package-private constructor com.intellij.util.containers.WeakKeyWeakValueHashMap.<init>() inaccessible to a class gw.gosu.ij.codeInsight.GosuBaseExternalAnnotationsManager. This can lead to **IllegalAccessError** exception at runtime.
#Package 'org.objectweb' is not found
Package 'org.objectweb' is not found along with its 4 classes.
Probably the package 'org.objectweb' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to **NoSuchClassError**.
The following classes of 'org.objectweb' are not resolved:
Class org.objectweb.asm.MethodVisitor is referenced in
gw.gosu.ij.debug.ReloadClassesIndicatorCompiler.updateReloadClassesIndicator() : byte[]
gw.gosu.ij.debug.ReloadClassesIndicatorCompiler.visitStringOrNull(MethodVisitor mv, String value) : void
Class org.objectweb.asm.ClassWriter is referenced in
gw.gosu.ij.debug.ReloadClassesIndicatorCompiler.updateReloadClassesIndicator() : byte[]
Class org.objectweb.asm.Label is referenced in
gw.gosu.ij.debug.ReloadClassesIndicatorCompiler.updateReloadClassesIndicator() : byte[]
Class org.objectweb.asm.Opcodes is referenced in
gw.gosu.ij.debug.ReloadClassesIndicatorCompiler
#Invocation of unresolved method com.intellij.util.containers.ContainerUtilRt.newHashSet(int) : HashSet
Constructor gw.gosu.ij.codeInspection.codeStyle.AnonymousCanBeBlockInspection.ForbiddenRefsChecker.<init>(gw.gosu.ij.psi.GosuPsiMethod method, gw.gosu.ij.psi.GosuPsiAnonymousClass aClass) contains an *invokestatic* instruction referencing an unresolved method com.intellij.util.containers.ContainerUtilRt.newHashSet(int) : java.util.HashSet. This can lead to **NoSuchMethodError** exception at runtime.
#Invocation of unresolved constructor org.jetbrains.jps.builders.java.dependencyView.Mappings.<init>(File, boolean)
Constructor org.jetbrains.jps.builders.java.dependencyView.GosuMappings.<init>(java.io.File rootDir, boolean transientDelta) contains an *invokespecial* instruction referencing an unresolved constructor org.jetbrains.jps.builders.java.dependencyView.Mappings.<init>(java.io.File, boolean). This can lead to **NoSuchMethodError** exception at runtime.
#Access to unresolved field com.intellij.refactoring.JavaRefactoringSettings.MOVE_INNER_PREVIEW_USAGES : boolean
Method gw.gosu.ij.refactoring.move.moveInner.GosuMoveInnerDialog.doAction() : void contains a *putfield* instruction referencing an unresolved field com.intellij.refactoring.JavaRefactoringSettings.MOVE_INNER_PREVIEW_USAGES : boolean. This can lead to **NoSuchFieldError** exception at runtime.
#Access to unresolved field com.intellij.codeInsight.daemon.impl.HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER : HighlightInfoType
Method gw.gosu.ij.codeInsight.daemon.impl.analysis.GosuHighlightVisitorImpl.doVisitReferenceElement(gw.gosu.ij.psi.PsiGosuCodeReferenceElement e) : gw.gosu.ij.psi.GosuResolveResult contains a *getstatic* instruction referencing an unresolved field com.intellij.codeInsight.daemon.impl.HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER : com.intellij.codeInsight.daemon.impl.HighlightInfoType. This can lead to **NoSuchFieldError** exception at runtime.
#Invocation of unresolved method com.intellij.util.containers.ContainerUtilRt.newLinkedHashMap() : LinkedHashMap
Method gw.gosu.ij.psi.codeStyle.GosuRearranger.<clinit>() : void contains an *invokestatic* instruction referencing an unresolved method com.intellij.util.containers.ContainerUtilRt.newLinkedHashMap() : java.util.LinkedHashMap. This can lead to **NoSuchMethodError** exception at runtime.
Against IC-193.4932.9 the plugin gw.gosu.ij:h-latest-user-rberlin-ISSTUDIO-527-SNAPSHOT has 0 warnings
2019-11-11T16:29:29 [main] INFO verification - Total time spent downloading plugins and their dependencies: 0 ms
2019-11-11T16:29:29 [main] INFO verification - Total amount of plugins and dependencies downloaded: 0 B
2019-11-11T16:29:29 [main] INFO verification - Total amount of space used for plugins and dependencies: 0 B
Thanks for the detailed report and suggestions, we'll look into them.
BGoldberg: is this your plugin? https://plugins.jetbrains.com/plugin/7140-os-gosu All these errors are from upgrading 2019.2 vs 2019.3 only? Because the last release is marked as "2017.3.1 — 2017.3.7" only?! Are there sources available somewhere? Thanks. I"ll follow up on all the API breakages you listed.
Yes, that was apparently the last published version of our plugin in open source. My company has continued developing the Gosu plugin for distribution to our own customers, and skipped 2018 and went from 2017.3.7 to 2019.x, but unfortunately the two people who know how to create the open source distribution at Guidewire left the company a few years ago, which is apparently why there are no further published versions, even though we have been actively developing this plugin for our customers.
Guidewire has no objection to continuing publication of the plugin. I will try to investigate how to publish later versions of that plugin. If I am able to do so, or to provide you with sources of the 2019.1 plugin, it sounds like that will help JetBrains communicate with us what changes we need to make. Is that the case?
Meanwhile, if you could follow up and provide us some guidance of how to deal with those breakages, while I try to figure out how to publish what we have for 2019.1, that would help us greatly.
Actually, that's not our plugin, but rather Gosu (the language) itself.
Vladimir, regarding this:
> I would settle for having a @since java doc annotation for newly added or changed APIs with a minimum build number for its appearance
Actually this is already supported. We automatically generate '@ApiStatus.AvailableSince' annotations which describe build where API was introduced and publish them to IntelliJ Artifacts repository. If you use gradle-intellij-plugin to develop your plugin, these annotations will be automatically attached to the library when you import the project in IntelliJ IDEA, and there is an inspection which will show a warning if you for example access a method introduced in 192.xxx build while your plugin.xml has since-build=191.*.
BGoldberg, thanks for clarifying the publication status. Indeed, having a (recent) published version of your plugin on plugins.jetbrains.com is required for us to be aware of such problems. Publishing the sources is not necessary for the verification process, but may help in assisting on required changes.
I've updated the Breaking API Changes page http://www.jetbrains.org/intellij/sdk/docs/reference_guide/api_changes/api_changes_list_2019.html with some more items and hope to follow up with more in the next few days once I received necessary information.
Please follow this issue https://youtrack.jetbrains.com/issue/MP-2733 to track the ideas proposed above.