All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.echocat.jomon.spring.Boot Maven / Gradle / Ivy

/*****************************************************************************************
 * *** BEGIN LICENSE BLOCK *****
 *
 * Version: MPL 2.0
 *
 * echocat Jomon, Copyright (c) 2012-2013 echocat
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * *** END LICENSE BLOCK *****
 ****************************************************************************************/

package org.echocat.jomon.spring;

import org.echocat.jomon.runtime.Log4JUtils;
import org.echocat.jomon.runtime.ManifestInformationFactory;
import org.echocat.jomon.runtime.concurrent.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import java.lang.reflect.Field;

import static java.lang.Thread.currentThread;
import static org.echocat.jomon.runtime.io.UrlUtils.registerUrlStreamHandlerIfNeeded;

public class Boot {

    static {
        registerUrlStreamHandlerIfNeeded();
    }

    private static final Logger LOG = LoggerFactory.getLogger(Boot.class);
    
    private static ManifestInformationFactory c_informationFactory = new ManifestInformationFactory(Boot.class);

    public static void main(String[] args) {
        if (args == null || (args.length != 1 && args.length != 2)) {
            //noinspection UseOfSystemOutOrSystemErr
            System.err.println("java -cp  " + Boot.class.getName() + "  [log4j configuration in classpath]");
            //noinspection CallToSystemExit
            System.exit(1);
        } else {
            start(args[0], args.length == 2 ? args[1] : null);
        }
    }

    @Nonnull
    public static ConfigurableApplicationContext start(@Nonnull Class reference, @Nonnull String bootBeanXmlFileName) {
        return start(reference, bootBeanXmlFileName, null);
    }

    @Nonnull
    public static ConfigurableApplicationContext start(@Nonnull Class reference, @Nonnull String bootBeanXmlFileName, @Nullable String log4jConfigurationFileName) {
        final String bootBeanXmlInClassPath = fullElementPath(reference, bootBeanXmlFileName);
        final String log4jConfigurationInClassPath = log4jConfigurationFileName != null ? fullElementPath(reference, log4jConfigurationFileName) : null;
        return start(bootBeanXmlInClassPath, log4jConfigurationInClassPath);
    }

    @Nonnull
    public static ConfigurableApplicationContext start(@Nonnull String bootBeanXmlInClassPath) {
        return start(bootBeanXmlInClassPath, null);
    }

    @Nonnull
    public static ConfigurableApplicationContext start(@Nonnull String bootBeanXmlInClassPath, @Nullable String log4jConfigurationInClassPath) {
        configureInformationFactory(bootBeanXmlInClassPath);
        configureLog4j(log4jConfigurationInClassPath);
        return startComponent(bootBeanXmlInClassPath, getApplicationName());
    }

    @Nonnull
    public static ConfigurableApplicationContext startComponent(@Nonnull String bootBeanXmlInClassPath, @Nonnull final String applicationName) {
        return startComponent(null, bootBeanXmlInClassPath, applicationName);
    }

    @Nonnull
    public static ConfigurableApplicationContext startComponent(@Nullable ApplicationContext parent, @Nonnull String bootBeanXmlInClassPath, @Nonnull final String applicationName) {
        final StopWatch stopWatch = new StopWatch();
        LOG.info("Starting " + applicationName + "...");
        final ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] {bootBeanXmlInClassPath}, false, parent);
        final Thread shutdownHook = new Thread("destroyer") { @Override public void run() {
            LOG.info("Stopping " + applicationName + "...");
            applicationContext.close();
            LOG.info("Stopping " + applicationName + "... DONE!");
        }};
        boolean success = false;
        boolean applicationContextStarted = false;
        try {
            applicationContext.refresh();
            applicationContextStarted = true;
            waitForContextLoadThreads(applicationContext);
            setShutdownHook(shutdownHook, applicationContext);
            Runtime.getRuntime().addShutdownHook(shutdownHook);
            LOG.info("Starting " + applicationName + "... DONE! (after: " + stopWatch + ")");
            success = true;
        } finally {
            if (applicationContextStarted && !success) {
                applicationContext.close();
            }
        }
        return applicationContext;
    }

    @Nonnull
    public static String fullElementPath(@Nonnull Class reference, @Nonnull String element) {
        return reference.getPackage().getName().replace('.', '/') + '/' + element;
    }

    @Nonnull
    public static ManifestInformationFactory getInformationFactory() {
        return c_informationFactory;
    }

    @Nonnull
    public static String getApplicationName() {
        final String applicationInfoString = c_informationFactory.getApplicationInfoString();
        return applicationInfoString != null ? applicationInfoString : Boot.class.getName();
    }

    private static void configureInformationFactory(String bootBeanXmlInClassPath) {
        c_informationFactory = new ManifestInformationFactory(bootBeanXmlInClassPath, Boot.class.getClassLoader());
    }

    public static void configureLog4j(@Nullable String log4jConfigurationInClassPath) {
        Log4JUtils.configureRuntime(log4jConfigurationInClassPath != null ? Boot.class.getClassLoader().getResource(log4jConfigurationInClassPath) : Boot.class.getResource("default.log4j.xml"));
    }

    protected static void waitForContextLoadThreads(@Nonnull AbstractApplicationContext applicationContext) {
        try {
            for (ContextLoadThreadGroup contextLoadThreadGroup : applicationContext.getBeansOfType(ContextLoadThreadGroup.class).values()) {
                contextLoadThreadGroup.join();
            }
        } catch (InterruptedException ignored) {
            currentThread().interrupt();
        }
    }

    protected static void setShutdownHook(@Nonnull Thread thread, @Nonnull AbstractApplicationContext to) {
        try {
            final Field field = AbstractApplicationContext.class.getDeclaredField("shutdownHook");
            field.setAccessible(true);
            field.set(to, thread);
        } catch (Exception e) {
            LOG.warn("Could not register shutdownHook at " + to + " this could cause to much memory consume of the JVM.", e);
        }
    }

    private Boot() {}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy