Mixing different extension points in one plugin

Answered

I'm working on donated Struts2 plugin and I would like to change all the packages from com.intellij.struts2 into org.apache.struts.

Yet this affects <extensions/> definition in plugin.xml. To get my extension points to work I must specify defaultExtensionNs="org.apache.struts" but then the built-in extension points don't work, eg: <com.intellij.facetType implementation="org.apache.struts.facet.StrutsFacetType"/> because “Cannot resolve extension point 'org.apache.struts.com.intellij.facetType' in dependencies” and the defaultExtensionNs attribute is required.

0
6 comments

Hi Łukasz,

I'm sorry, but I don't understand how it affects <extensions/>. It seems that you try to use a platform EP (com.intellij.facetType) under extensions with a default namespace org.apache.struts. It concatenates the default namespace to the declared extension point name and the platform tries to resolve org.apache.struts.com.intellij.facetType, which doesn't exist.

If you use platform extension points and EPs from your plugin, you should declare separate <extensions/> elements:

  1. For platform with defaultExtensionNs="com.intellij" - then you can declare <facetType implementation="org.apache.struts.facet.StrutsFacetType"/> (without qualified name com.intellij.facetType)
  2. For your plugin extensions (if there are any custom <extensionPoints/> in your plugin) with defaultExtensionNs="<your plugin ID>".

More about declaring extensions: https://plugins.jetbrains.com/docs/intellij/plugin-extensions.html#declaring-extensions

0

Exactly, I cannot mix these two. Currently plugin overcomes this limitation by using the same packages names as the platform ("com.intellij")  and this allows at the same time define new extension points using “<extensionPoints/>” [1]  and extend existing one from the Platform [2].

If the attribute “defaultExtensionNs” would be optional it would be possible to achieve the same by using different package names and FQDN names of extension points.

[1] https://github.com/apache/struts-intellij-plugin/blob/main/src/main/resources/META-INF/plugin.xml#L42-L53

[2] https://github.com/apache/struts-intellij-plugin/blob/main/src/main/resources/META-INF/plugin.xml#L56

 

0

Lukasz Lenart Unless I'm misunderstanding your problem, you can just have multiple <extension> elements:

<extensions defaultExtensionNs="com.intellij">
  ...
</extensions>
<extensions defaultExtensionNs="org.apache.struts">
  <facetType implementation="org.apache.struts.facet.StrutsFacetType"/>
  ...
</extensions>
0

The plugin is identified by id = <id>com.intellij.struts2</id> and itself defines a few new extension points:

<extensionPoints>
	<extensionPoint name="constantContributor" interface="com.intellij.struts2.model.constant.StrutsConstantContributor" dynamic="true"/>
    ...

(constantContributor is expanded into com.intellij.struts2.constantContributor - combination of id of the plugin and name of the extension point)

These extension points are then used in the plugin itself:

<extensions defaultExtensionNs="com.intellij">
	...
	<struts2.constantContributor implementation="com.intellij.struts2.model.constant.contributor.StrutsCoreConstantContributor"/>
	...

This works just because all of them are using com.intellij as package name/id.

My problem is that I want to use a different package eg. org.apache.struts for my plugin, but because defaultExtensionNs is required it won't work.

The only option to define <extensionsPoints/> and be able to use them inside <extensions/> is to use com.intellij in all places - a dirt hack.

0

Hi Łukasz,

I'm confused about what you want to do.

Do you want to change just the package or the plugin ID? These are different and independent things.

You can use whatever Java packages you want in your plugin, and it doesn't have to be consistent with the ID.

The ID can be set once, and you can't change it once it was uploaded to JetBrains Marketplace. Please note that this is just a technical ID and it is not used in UI. If it is still crucial to change, it will be a new plugin on the marketplace, and your users won't be able to update to the version with the new ID. You can influence your users to migrate to the new plugin with PluginReplacement (you should implement it in your “old” plugin and it will point users to the new one). If the reason for changing the ID is restricted usage of the "intellij" word, then you can ignore this error - it is forbidden for new plugins only.

If you decide to keep the old plugin ID, then you should create an additional <extensions> element:

<extensions defaultExtensionNs="com.intellij.struts2">
    <constantContributor
            implementation="com.intellij.struts2.model.constant.contributor.StrutsCoreConstantContributor"/>
    <constantContributor
            implementation="com.intellij.struts2.model.constant.contributor.StrutsConventionPluginConstantContributor"/>
    <constantContributor
            implementation="com.intellij.struts2.model.constant.contributor.StrutsOSGiPluginConstantContributor"/>
    <constantContributor
            implementation="com.intellij.struts2.model.constant.contributor.StrutsSpringPluginConstantContributor"/>
    <constantContributor
            implementation="com.intellij.struts2.model.constant.contributor.StrutsRESTPluginConstantContributor"/>

    <resultContributor
            implementation="com.intellij.struts2.dom.struts.impl.path.DispatchPathResultContributor"/>
    <resultContributor
            implementation="com.intellij.struts2.dom.struts.impl.path.ActionPathResultContributor"/>
    <resultContributor
            implementation="com.intellij.struts2.dom.struts.impl.path.ActionChainOrRedirectResultContributor"/>

    <paramNameCustomConverter
            implementation="com.intellij.struts2.dom.params.custom.InterceptorRefInStackParamNameCustomConverter"/>
    <paramNameCustomConverter
            implementation="com.intellij.struts2.dom.params.custom.ResultParamNameCustomConverter"/>

</extensions>

Or use the new plugin ID in defaultExtensionNs. Please note that using new ID will make these EP names change incompatible with plugins implementing them (if there are any).

0

Ok, let me check again, but I recall IDEA was complaining about ID not matching the packages

0

Please sign in to leave a comment.