Hi all,
While chasing the rc-6 IntelliJ breakage I ran into something I think deserves
a separate discussion. The immediate bug is small and already has a fix —
#13068 <https://github.com/apache/maven/issues/13068> / PR #13069
<https://github.com/apache/maven/pull/13069>: rc-6 added two abstract methods
to the internal PluginDependenciesResolver, which breaks out-of-tree
implementations with AbstractMethodError, and making them default restores
compatibility.
The trigger was Apache PLC4X becoming unusable in IntelliJ, reported by
Christofer Dutz on their dev list ("[DISCUSS] Downgrade to maven 4 RC-5?"
<https://lists.apache.org/thread/pkry4orbrl5nndnocgwzk6l5137tkyzp>), who also
verified the fix. Guillaume root-caused it in reply to Sergey Chernov's -1 on
the rc-6 vote
<https://lists.apache.org/thread/mtt7kg632lfs2hxcx0nv9bn4omkgbvt6>.
The question I would like to raise is why that broke anything at all.
Three IDEs override the same internal component
IDE Class How
IntelliJ IDEA Maven40PluginDependenciesResolver
<https://github.com/JetBrains/intellij-community/blob/master/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40PluginDependenciesResolver.java>
implements the interface, @Priority(10)
Eclipse m2e EclipsePluginDependenciesResolver
<https://github.com/eclipse-m2e/m2e-core/blob/main/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/EclipsePluginDependenciesResolver.java>
extends DefaultPluginDependenciesResolver
NetBeans NbPluginDependenciesResolver
<https://github.com/apache/netbeans/blob/master/java/maven.embedder/src/org/netbeans/modules/maven/embedder/impl/NbPluginDependenciesResolver.java>
extends DefaultPluginDependenciesResolver
That is every major Java IDE, independently, on an interface whose javadoc says
it "can be changed or deleted without prior notice".
Two of the three do it for the identical reason: workspace resolution must not
apply to plugin resolution. Resolver's WorkspaceReader is session-scoped with
no plugin-versus-dependency distinction, so the only way to say "resolve
plugins from the repository, not from my workspace" is to wrap our component
and toggle the reader around the call. m2e disables
EclipseWorkspaceArtifactRepository, NetBeans calls NbWorkspaceReader.silence().
IntelliJ's case is thinner — a retry decorator around our own implementation.
m2e's source still carries the citation:
Plugin realms are cached and there is currently no way to purge cached realms
due to MNG-4194. Workspace plugins cannot be cached, so we disable this until
MNG-4194 is fixed.
MNG-4194 is #5961 <https://github.com/apache/maven/issues/5961>, "API to safely
release of plugin realms", opened in 2009 and closed in 2010 with the comment
"Now working correctly in M2E". An API request, closed because the consumer's
workaround worked. Sixteen years later the workaround is still there, in three
products.
Maven 4 offers no alternative
org.apache.maven.api.spi
<https://github.com/apache/maven/tree/maven-4.0.x/api/maven-api-spi/src/main/java/org/apache/maven/api/spi>
currently contains ExtensibleEnumProvider, LanguageProvider,
LifecycleProvider, ModelParser, ModelTransformer, PackagingProvider,
PathScopeProvider, ProjectScopeProvider, PropertyContributor, TypeProvider and
SpiService. All of it concerns the model, the lifecycle and the type system.
Nothing touches artifact or plugin resolution.
So an embedder that needs to influence resolution has exactly one door, and it
is the one we reserve the right to close without notice. We then did change it,
mid-RC-vote, and IntelliJ broke for every user of a project that declares core
extensions.
Possible directions
I am not attached to any of these; I would like to know which one the project
considers right.
Document the contract instead of adding API: state that plugin and extension
resolution bypasses the WorkspaceReader. If that is the intended behaviour
anyway, two of the three overrides disappear.
Make the distinction expressible — a session or request scoped flag, or a
separate workspace reader for plugin resolution.
A minimal supported SPI for plugin/extension resolution.
Decide explicitly that embedders are on their own. That is a legitimate answer
— Maven 4 deliberately shrank its public surface, and a resolution SPI is a
real maintenance commitment. But then I think we should say so plainly, rather
than leave one internal door ajar and let three IDEs walk through it for
fifteen years.
Whatever we choose, adding methods to a widely implemented interface as default
rather than abstract costs us nothing and avoids this class of breakage —
that part is just hygiene.
On timing: I am explicitly not proposing this as a 4.0.0 blocker — the fix in
PR #13069 is what 4.0.0 needs. But I would not want to rule 4.0.0 out either.
If the answer turns out to be option 1, or a very small additive SPI, it may be
worth weighing whether it still fits before GA rather than waiting for 4.1 —
an addition made after GA is harder to place than one made with it. That
judgement is the project's, not mine.
Input from the IDE side would be worth more than my reading of their source.
Marit van Dijk, Nikita Skvortsov, Sergey Chernov (JetBrains) what do you
actually need from Maven here, and would option 1 or 2 be enough to let you
drop the override? The same question to whoever is closest to m2e and NetBeans.
Regards,
Gerd
--
Gerd Aschemann (er/he) --- Veröffentlichen heißt Verändern (Carmen Thomas)
+49/173/3264070 -- [email protected] -- https://aschemann.net