I was working with Weld framework in a Java SE environment largely through the IDE, and had found posts about using the org.jboss.weld.environment.se.StartMain class to bootstrap Weld from within Java SE, but I wanted more control over which class was targeted as the prescribed approach of having a ContainerInitialized event listener ala:

 

public class TestMain {
    public void main(@Observes ContainerInitialized event, @Parameters List parameters) {
        System.out.printf("TestMain.main called, parameters=%s\n", parameters);
    }
}

 

would result in every such listener in the ide classpath being called. I took the simple StartMain bootstrap code and created the following CustomWeldStartMain that accepts the name of the class to use as the post bootstrap entry point:

 

package com.si.weld;


import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;


/**
 * A weld startup class for use in Java SE environment
 *
 * @author Scott Stark
 * @version $Revision:$
 */
public class CustomWeldStartMain {


    /**
     * The entry point to the weld initialization
     * @param args - the
     *             [0] = the class name of WeldMain class to bootstrap
     *             [1..n] = the args to pass to the WeldMain.main(String...) method
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // Need at least one arg giving the WeldMain implementation class name
        if(args.length == 0) {
            throw new IllegalStateException("Non-zero arguments required, first argument must be main class name");
        }
        // Load the class to use as the main class
        String mainClassName = args[0];
        Class<?> mainClass = CustomWeldStartMain.class.getClassLoader().loadClass(mainClassName);
        if(WeldMain.class.isAssignableFrom(mainClass) == false) {
            throw new IllegalStateException(mainClassName+"does not implement WeldMain");
        }
        Class<WeldMain> weldMainClass = (Class<WeldMain>) mainClass;
        // Standard Weld bootstrap from org.jboss.weld.environment.se.StartMain
        Weld weld = new Weld();
        WeldContainer weldContainer = weld.initialize();
        WeldMain main = weldContainer.instance().select(weldMainClass).get();
        // Add the SE shutdown hook
        Runtime.getRuntime().addShutdownHook(new ShutdownHook(weld));
        // Call the WeldMain.main() entry point
        String[] subargs = new String[args.length-1];
        System.arraycopy(args, 1, subargs, 0, args.length-1);
        main.main(subargs);
    }


    static class ShutdownHook extends Thread {
        private final Weld weld;


        ShutdownHook(final Weld weld) {
            this.weld = weld;
        }


        public void run() {
            weld.shutdown();
        }
    }
}

package com.si.weld;


/**
 * A simple interface defining the Weld post bootstrap main entry point.
 * 
 * @author Scott Stark
 * @version $Revision:$
 */
public interface WeldMain {
    public void main(String[] args) throws Exception;
}

 

Here is a sample test WeldMain entry point that is invoked when running from within the ide using a

 

package test.com.si.weld;


import com.si.weld.WeldMain;


import javax.inject.Singleton;
import java.util.Arrays;


/**
 * A minimalist WeldMain implementation
 *
 * @author Scott Stark
 * @version $Revision:$
 */
@Singleton
public class TestMain2 implements WeldMain {
    public void main(String[] args) {
        System.out.printf("TestMain2.main(%s)\n", Arrays.asList(args));
    }
}

 

 

To run this class, I setup a run configuration that specified com.si.weld.CustomWeldStartMain as the main class, and included test.com.si.weld.TestMain2 as the first program argument, with arg2, arg3 as the second argument. Running this within the ide produced:

 

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java -Didea.launcher.port=7537 "..." com.intellij.rt.execution.application.AppMain com.si.weld.CustomWeldStartMain test.com.si.weld.TestMain2 arg2 arg3

45 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.9 (Final)

263 [main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.

TestMain2.main([arg2, arg3])

Process finished with exit code 0

 

Maybe this is of general interest as an alternative StartMain?