eclipse-pluginweld-se

Weld CDI inside eclipse plugin


I have a third-party library which uses weld, specifically weld-se-2.4.5. I want to make use of this library inside a plugin for a different third-party application that's using the eclipse plugin framework. I cannot for the life of me get Weld to initialise successfully.

I can't share either of the real applications, but I've made a minimal example plugin that I also can't get to work for what I hope is the same reasons.

Activator.java:

package minimal_cdi;

import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator extends AbstractUIPlugin {

    // The plug-in ID
    public static final String PLUGIN_ID = "minimal-cdi"; //$NON-NLS-1$

    // The shared instance
    private static Activator plugin;
    
    private static WeldContainer container;
    
    /**
     * The constructor
     */
    public Activator()
    {
    }

    @Override
    public void start(BundleContext context) throws Exception
    {
        super.start(context);
        plugin = this;
        try
        {
            Weld weld = new Weld().property("org.jboss.weld.se.shutdownHook", false);
    
            container = weld.initialize();
            container.select(MainClass.class).get().start();
    
            Runtime.getRuntime().addShutdownHook( new Thread( () -> {
                container.select(MainClass.class).get().shutdown();
                container.shutdown();
            }));
        }
        catch (Exception e)
        {
            System.err.println(e.toString());
        }       
    }

    @Override
    public void stop(BundleContext context) throws Exception {
        plugin = null;
        super.stop(context);
    }

    /**
     * Returns the shared instance
     *
     * @return the shared instance
     */
    public static Activator getDefault() {
        return plugin;
    }
}

Main class:

package minimal_cdi;

import javax.inject.Inject;


public class MainClass
{
    @Inject
    ThingDoer doer;
    
    MainClass()
    {
    }
    
    MainClass(ThingDoer doerIn)
    {
        doer = doerIn;
    }
    
    void start()
    {
        doer.doThing();
    }
    
    void shutdown()
    {
        doer.stop();
    }
}

Interface to inject:

package minimal_cdi;

public interface ThingDoer
{
    abstract public void doThing();
    abstract public void stop();
}

Implementation of the interface:

package minimal_cdi;

public class BeanieBoo implements ThingDoer
{
    @Override
    public void doThing()
    {
    System.out.println("Hello World");
    }

    public void stop()
    {
    System.out.println("Goodbye");
    }   
}

beans.xml

<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

I export the plugin and run it through the OSGI console and get the following output:

Sept 24, 2024 10:57:47 AM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 2.4.5 (Final)
Sept 24, 2024 10:57:47 AM org.jboss.weld.environment.deployment.discovery.DefaultBeanArchiveScanner getBeanArchiveReference
WARN: Unable to adapt URL: bundleresource://892.fwk1603300106:1/META-INF/beans.xml, using its external form instead
Sept 24, 2024 10:57:47 AM org.jboss.weld.environment.deployment.discovery.AbstractDiscoveryStrategy performDiscovery
WARN: WELD-ENV-000031: The bean archive reference bundleresource://892.fwk1603300106:1/META-INF/beans.xml cannot be handled by any BeanArchiveHandler: [org.jboss.weld.environment.deployment.discovery.FileSystemBeanArchiveHandler@ea1ce9b]
java.lang.IllegalStateException: WELD-ENV-002009: Weld SE container cannot be initialized - no bean archives found

Solution

  • WARN: WELD-ENV-000031: The bean archive reference bundleresource://892.fwk1603300106:1/META-INF/beans.xml cannot be handled by any BeanArchiveHandler: [org.jboss.weld.environment.deployment.discovery.FileSystemBeanArchiveHandler@ea1ce9b]

    This will not work as Weld has no implementation of BeanArchiveHandler that would know how to deal with the resource you are passing it. I suppose the bundleresource://892.fwk1603300106:1/META-INF/beans.xml format is eclipse specific and as such Weld refuses it, not knowing how to parse its contents.