| When a JAR extension overrides an existing component by declaring a priority in its META-INF/components.txt (e.g. 500:org.example.MyCodeMacro), uninstalling the extension doesn't unregister that component: it stays registered (and used) until XWiki is restarted, even though the extension is reported as uninstalled and its JAR is no longer in the extension class loader. Steps to reproduce, on XWiki 18.8.0:
- Create a page containing {{code language="python"}}print("hi"){{/code}}.
- Install the "Prism.js Code Macro Replacement" extension (org.xwiki.contrib.prismjs:prismjs-code 1.3) on the farm. Its components.txt declares 500:org.xwiki.contrib.prismjs.internal.PrismCodeMacro, which overrides the code macro.
- View the page: it's rendered by the Prism.js macro, as expected.
- Uninstall the extension.
- View the page again, or a page created after the uninstall.
Result: the page is still rendered by the Prism.js macro. The root component manager still returns PrismCodeMacro (priority 500) for Macro/code, loaded from the previous extension class loader. Expected: the component is unregistered when the extension is uninstalled. Cause: ComponentAnnotationLoader registers the components with the priority read from components.txt (componentDeclaration.getPriority()), but ComponentAnnotationLoader#unregister() rebuilds the descriptors with getComponentsDescriptors(componentClass), which uses ComponentDescriptor.DEFAULT_PRIORITY (1000). EmbeddableComponentManager#unregisterComponent(ComponentDescriptor) only removes the component when the registered descriptor equals() the passed one, and DefaultComponentDescriptor#equals() compares roleHintPriority (500 vs 1000), so the call silently does nothing. Checked on a live 18.8.0 instance: the computed descriptor matches the registered one on everything except roleHintPriority. The fix is to pass componentDeclaration.getPriority() when computing the descriptors to unregister. Note that once this is fixed, uninstalling such an extension will leave no component at all for the overridden role/hint (the original one was dropped when the override was registered), which is XCOMMONS-85. |