@ModuleType doesn't work in Confluence 8.9

The implementation of pluginAccessor.getEnabledModulesByClass(clazz) in Confluence 8.9 is unstable for us, and often returns an empty list. It depends on the customer’s installation, it doesn’t seem deterministic.

Is this unstability a bug of the Atlassian framework in Confluence 8.9? Is it caused by some prerequisite that we didn’t fulfill? Help, we’re stuck, we have very large customers and we don’t want the issues to get larger.

We have a module type defined like this:

<yogi-queue-handler key="indexing-queue-handler" class="com.requirementyogi.datacenter.confluenceapp.indexing.IndexingQueueHandler"/>
<yogi-queue-handler ... (x7)

With a module descriptor defined like this:

@Component
public class QueueHandlerModuleTypeDescriptor extends YogiModuleTypeDescriptor<QueueHandler<?>> {
    
    private QueueHandler<?> module = null;

    public QueueHandlerModuleTypeDescriptor(final @ComponentImport ModuleFactory moduleFactory) {
        super(moduleFactory);
    }

    @Override
    public QueueHandler<?> getModule() {
        if (module == null) {
            module = moduleFactory.createModule(this.moduleClassName, this);
        }
        return module;
    }
}

The type factory is like this:

@ModuleType(ListableModuleDescriptorFactory.class)
@Component
public class QueueHandlerModuleTypeFactory extends SingleModuleDescriptorFactory<QueueHandlerModuleTypeDescriptor>
{
    @Autowired
    public QueueHandlerModuleTypeFactory(final HostContainer hostContainer)
    {
        super(hostContainer, "yogi-queue-handler", QueueHandlerModuleTypeDescriptor.class);
    }
}

When we use the following line, sometimes it returns nothing, sometimes it returns the 7 implementations of QueueHandler.class:

list1 = pluginAccessor.getEnabledModulesByClass(QueueHandler.class);
// We've also tried this, but it only returns the implementations of the current plugin,
// which is wrong because other plugins may define components implementing QueueHandler:
list2 = listableBeanFactory.getBeansOfType(QueueHandler.class);

NB: In all of the classes above, the imports are from the following packages:


import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.PluginAccessor;
import com.atlassian.plugin.PluginInformation;
import com.atlassian.plugin.hostcontainer.HostContainer;
import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
import com.atlassian.plugin.module.ModuleFactory;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.stereotype.Component;
import com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory;
import com.atlassian.plugin.osgi.external.SingleModuleDescriptorFactory;
import com.atlassian.plugin.spring.scanner.annotation.export.ModuleType;

The pom.xml contains:


    <Spring-Context>*</Spring-Context>
    <Atlassian-Plugin-Key>com.requirementyogi.confluence-app</Atlassian-Plugin-Key>
    <Atlassian-Scan-Folders>META-INF/plugin-descriptors</Atlassian-Scan-Folders>
    <Import-Package>
        ...
        <!-- For the @Component annotation scanning -->
        org.springframework.stereotype;version="0.0.0",
        org.springframework.lang;version="0.0.0",
        org.springframework.beans;version="0.0.0",
        org.springframework.beans.factory;version="0.0.0",
        org.springframework.beans.factory.config;version="0.0.0",
        org.springframework.beans.factory.annotation;version="0.0.0",
        org.springframework.util;version="0.0.0",
        com.atlassian.spring.container;version="0.0.0",
        org.springframework.cglib.core,
        org.springframework.cglib.proxy,
        org.springframework.cglib.reflect,

        <!-- For @ModuleType -->
        com.atlassian.plugin.hostcontainer;resolution:=optional;version="0.0.0",
        <!--org.springframework.context;resolution:=optional;version="0.0.0",-->
        com.atlassian.plugin.osgi.external;resolution:=optional;version="0.0.0",
        com.atlassian.plugin.osgi.bridge.external;version="0.0.0"
1 Like