users@glassfish.java.net

Making a standalone with hk2

From: <glassfish_at_javadesktop.org>
Date: Fri, 25 Jan 2008 02:19:58 PST

Hi,

After last update of hk2 I am experiencing a problem with compilation one of my modules that is responsible for running all other hk2 modules from the console (like a standalone).
Some time ago I got this code from some site and now it is not working:


/*
 * Main.java
 *
 * Created on October 17, 2006, 11:28 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.teliasonera.ct.test.automation.ttt.kickstart;

import static com.sun.hk2.component.InhabitantsFile.CLASS_KEY;
import static com.sun.hk2.component.InhabitantsFile.INDEX_KEY;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Logger;

import org.jvnet.hk2.component.ComponentException;
import org.jvnet.hk2.component.Habitat;

import com.sun.enterprise.module.ManifestConstants;
import com.sun.enterprise.module.Module;
import com.sun.enterprise.module.ModulesRegistry;
import com.sun.enterprise.module.ModuleMetadata.InhabitantsDescriptor;
import com.sun.enterprise.module.bootstrap.BootException;
import com.sun.enterprise.module.bootstrap.ModuleStartup;
import com.sun.enterprise.module.bootstrap.StartupContext;
import com.sun.enterprise.module.common_impl.DirectoryBasedRepository;
import com.sun.hk2.component.ExistingSingletonInhabitant;
import com.sun.hk2.component.KeyValuePairParser;

/**
 * CLI entry point that will setup the module subsystem and delegate the
 * main execution to the first archive in its import list...
 *
 * TODO: reusability of this class needs to be improved.
 *
 * @author dochez
 */
public class Main {

    public static void main(final String[] args) {
        (new Main()).run(args);
    }

    public void run(final String[] args) {
        try {
            final Main main = this;
            Thread thread = new Thread() {
                public void run() {
                    try {
                        main.start(args);
                    } catch(BootException e) {
                        e.printStackTrace();
                    } catch (RuntimeException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
            try {
                thread.join();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /**
     * We need to determine which jar file has been used to load this class
     * Using the getResourceURL we can get this information, after that, it
     * is just a bit of detective work to get the file path for the jar file.
     *
     * @return
     * the path to the jar file containing this class.
     * always returns non-null.
     *
     * @throws BootException
     * If failed to determine the bootstrap file name.
     */
    protected File getBootstrapFile() throws BootException {
        String resourceName = getClass().getName().replace(".","/")+".class";
        URL resource = getClass().getClassLoader().getResource(resourceName);
        if (resource==null) {
            throw new BootException("Cannot get bootstrap path from "
                    + resourceName + " class location, aborting");
        }

        if (resource.getProtocol().equals("jar")) {
            try {
                JarURLConnection c = (JarURLConnection) resource.openConnection();
                URL jarFile = c.getJarFileURL();
                File f = new File(jarFile.toURI());
                return f;
            } catch (IOException e) {
                throw new BootException("Cannot open bootstrap jar file", e);
            } catch (URISyntaxException e) {
                throw new BootException("Incorrect bootstrap class URI", e);
            }
        } else
            throw new BootException("Don't support packaging "+resource+" , please contribute !");
    }

    /**
     * Start the server from the command line
     * @param args the command line arguments
     */
    public void start(String[] args) throws BootException {
        File bootstrap = new File("file.jar"); //this.getBootstrapFile();
        File root = bootstrap.getAbsoluteFile().getParentFile();

        // root is the directory in which this bootstrap.jar is located
        // For most cases, this is the lib directory although this is completely
        // dependent on the usage of this facility.
        if (root==null) {
            throw new BootException("Cannot find root installation from "+bootstrap);
        }

// String targetModule = findMainModuleName(bootstrap);
        String targetModule = "com.teliasonera.ct.test.automation.ttt.core:baby";

        // get the ModuleStartup implementation.
        ModulesRegistry mr = ModulesRegistry.createRegistry();
        createRepository(root,mr);

        launch(mr, targetModule, root, args);
    }

    /**
     * Creates repositories needed for the launch and
     * adds the repositories to {_at_link ModulesRegistry}
     */
    protected void createRepository(File root, ModulesRegistry mr) throws BootException {
        try {
            DirectoryBasedRepository lib = new DirectoryBasedRepository("lib", root);
            lib.initialize();
            mr.addRepository(lib);
            mr.setParentClassLoader(this.getClass().getClassLoader());
        } catch(IOException ioe) {
            throw new BootException("Error while initializing lib repository at : "+root, ioe);
        }
    }

    /**
     * Launches the module system and hand over the execution to the {_at_link ModuleStartup}
     * implementation of the main module.
     *
     * <p>
     * This version of the method auto-discoveres the main module.
     * If there's more than one {_at_link ModuleStartup} implementation, it is an error.
     *
     * @param root
     * This becomes {_at_link StartupContext#getRootDirectory()}
     * @param args
     * This becomes {_at_link StartupContext#getArguments()}
     *
     */
    public void launch(ModulesRegistry registry, File root, String[] args) throws BootException {

        Habitat mgr = registry.newHabitat();
        StartupContext context = new StartupContext(root, args);
        mgr.add(new ExistingSingletonInhabitant<StartupContext>(context));
        registry.createHabitat("default", mgr);

        Collection<ModuleStartup> startups = mgr.getAllByContract(ModuleStartup.class);
        if(startups.isEmpty())
            throw new BootException("No module has ModuleStartup");
        if(startups.size()>1) {
            Iterator<ModuleStartup> itr = startups.iterator();
            throw new BootException("Multiple ModuleStartup found: "+itr.next()+" and "+itr.next());
        }

        ModuleStartup ms = startups.iterator().next();
        Module mainModule = new Module(ms);
                launch(ms, context, mainModule);
    }

    /**
     * Launches the module system and hand over the execution to the {_at_link ModuleStartup}
     * implementation of the main module.
     *
     * @param root
     * This becomes {_at_link StartupContext#getRootDirectory()}
     * @param args
     * This becomes {_at_link StartupContext#getArguments()}
     *
     */
    public void launch(ModulesRegistry registry, String mainModuleName, File root, String[] args) throws BootException {
        final String habitatName = "default"; // TODO: take this as a parameter

        // instantiate the main module, this is the entry point of the application
        // code. it is supposed to have 1 ModuleStartup implementation.
        final Module mainModule = registry.makeModuleFor(mainModuleName, null);
        if (mainModule == null) {
            if(registry.getModules().isEmpty())
                throw new BootException("Registry has no module at all");
            else
                throw new BootException("Cannot find main module " + mainModuleName+" : no such module");
        }

        String targetClassName = findModuleStartup(mainModule, habitatName);
        if (targetClassName==null) {
            throw new BootException("Cannot find a ModuleStartup implementation in the META-INF/services/com.sun.enterprise.v3.ModuleStartup file, aborting");
        }

        mainModule.setSticky(true);

        Class<? extends ModuleStartup> targetClass=null;
        ModuleStartup startupCode;

        StartupContext context = new StartupContext(root, args);
        
        ClassLoader currentCL = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(mainModule.getClassLoader());
            try {
                targetClass = mainModule.getClassLoader().loadClass(targetClassName).asSubclass(ModuleStartup.class);
                Habitat mgr = registry.newHabitat();
                mgr.add(new ExistingSingletonInhabitant<StartupContext>(context));
                mgr.add(new ExistingSingletonInhabitant<Logger>(Logger.global));
                startupCode = registry.createHabitat(habitatName, mgr).getComponent(targetClass);
            } catch (ClassNotFoundException e) {
                throw new BootException("Unable to load "+targetClassName,e);
            } catch (ComponentException e) {
                throw new BootException("Unable to load "+targetClass,e);
            }

            launch(startupCode, context, mainModule);
        } finally {
            Thread.currentThread().setContextClassLoader(currentCL);
        }

    }

    protected String findMainModuleName(File bootstrap) throws BootException {
        String targetModule;
        try {
            JarFile jarFile = new JarFile(bootstrap);
            Manifest manifest = jarFile.getManifest();

            Attributes attr = manifest.getMainAttributes();
            targetModule = attr.getValue(ManifestConstants.BUNDLE_IMPORT_NAME);
            if (targetModule==null) {
                throw new BootException("No Import-Bundles module found in manifest of " + bootstrap.getAbsoluteFile());
            }
        } catch(IOException ioe) {
            throw new BootException("Cannot get manifest from " + bootstrap.getAbsolutePath(), ioe);
        }
        return targetModule;
    }

    protected void launch(ModuleStartup startupCode, StartupContext context, Module mainModule) throws BootException {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        try {
            startupCode.setStartupContext(context);
            //Thread thread = new Thread(startupCode);
            //thread.setContextClassLoader(mainModule.getClassLoader());
            //
            //thread.start();
            //try {
            // thread.join();
            //} catch (InterruptedException e) {
            // e.printStackTrace();
            //}

            Thread.currentThread().setContextClassLoader(mainModule.getClassLoader());
            startupCode.run();
        } finally {
            Thread.currentThread().setContextClassLoader(cl);
        }
    }

    /**
     * Finds {_at_link ModuleStartup} implementation class name to perform the launch.
     *
     * <p>
     * This implementation does so by looking it up from services.
     */
    protected String findModuleStartup(Module mainModule, String habitatName) throws BootException {
        for(InhabitantsDescriptor d : mainModule.getMetadata().getHabitats(habitatName)) {
            try {
                for (KeyValuePairParser kvpp : d.createScanner()) {
                    for (String v : kvpp.findAll(INDEX_KEY)) {
                        if(v.equals(ModuleStartup.class.getName())) {
                            kvpp.rewind();
                            return kvpp.find(CLASS_KEY);
                        }
                    }
                }
            } catch (IOException e) {
                throw new BootException("Failed to parse "+d.systemId,e);
            }
        }

        throw new BootException("No "+ModuleStartup.class.getName()+" in "+mainModule);
    }
}
[Message sent by forum member 'antsh' (antsh)]

http://forums.java.net/jive/thread.jspa?messageID=255745