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

hudson.WebAppMain Maven / Gradle / Ivy

package hudson;

import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
import com.thoughtworks.xstream.core.JVM;
import hudson.model.Hudson;
import hudson.model.User;
import hudson.triggers.Trigger;
import hudson.util.IncompatibleVMDetected;
import hudson.util.RingBufferLogHandler;
import hudson.util.IncompatibleServletVersionDetected;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletResponse;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.TimerTask;
import java.util.logging.Logger;
import java.util.logging.Level;

/**
 * Entry point when Hudson is used as a webapp.
 *
 * @author Kohsuke Kawaguchi
 */
public class WebAppMain implements ServletContextListener {

    /**
     * Creates the sole instance of {@link Hudson} and register it to the {@link ServletContext}.
     */
    public void contextInitialized(ServletContextEvent event) {
        installLogger();

        File home = getHomeDir(event);
        home.mkdirs();
        System.out.println("hudson home directory: "+home);

        ServletContext context = event.getServletContext();

        // make sure that we are using XStream in the "enhenced" (JVM-specific) mode
        if(new JVM().bestReflectionProvider().getClass()==PureJavaReflectionProvider.class) {
            // nope
            context.setAttribute("app",new IncompatibleVMDetected());
            return;
        }

        // make sure this is servlet 2.4 container or above
        try {
            ServletResponse.class.getMethod("setCharacterEncoding",String.class);
        } catch (NoSuchMethodException e) {
            context.setAttribute("app,",new IncompatibleServletVersionDetected());
            return;
        }

        // Tomcat breaks XSLT with JDK 5.0 and onward. Check if that's the case, and if so,
        // try to correct it
        try {
            TransformerFactory.newInstance();
            // if this works we are all happy
        } catch (TransformerFactoryConfigurationError x) {
            // no it didn't.
            Logger logger = Logger.getLogger(WebAppMain.class.getName());

            logger.log(Level.WARNING, "XSLT not configured correctly. Hudson will try to fix this. See http://issues.apache.org/bugzilla/show_bug.cgi?id=40895 for more details",x);
            System.setProperty(TransformerFactory.class.getName(),"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
            try {
                TransformerFactory.newInstance();
                logger.info("XSLT is set to the JAXP RI in JRE");
            } catch(TransformerFactoryConfigurationError y) {
                logger.log(Level.SEVERE, "Failed to correct the problem.");
            }
        }


        try {
            context.setAttribute("app",new Hudson(home,context));
        } catch( IOException e ) {
            throw new Error(e);
        }

        // set the version
        Properties props = new Properties();
        try {
            InputStream is = getClass().getResourceAsStream("hudson-version.properties");
            if(is!=null)
                props.load(is);
        } catch (IOException e) {
            e.printStackTrace(); // if the version properties is missing, that's OK.
        }
        Object ver = props.get("version");
        if(ver==null)   ver="?";
        context.setAttribute("version",ver);

        Trigger.init(); // start running trigger

        // trigger the loading of changelogs in the background,
        // but give the system 10 seconds so that the first page
        // can be served quickly
        Trigger.timer.schedule(new TimerTask() {
            public void run() {
                User.get("nobody").getBuilds();
            }
        }, 1000*10);

    }

    /**
     * Installs log handler to monitor all Hudson logs.
     */
    private void installLogger() {
        RingBufferLogHandler handler = new RingBufferLogHandler();
        Hudson.logRecords = handler.getView();
        Logger.getLogger("hudson").addHandler(handler);
    }

    /**
     * Determines the home directory for Hudson.
     *
     * People makes configuration mistakes, so we are trying to be nice
     * with those by doing {@link String#trim()}.
     */
    private File getHomeDir(ServletContextEvent event) {
        // check JNDI for the home directory first
        try {
            Context env = (Context) new InitialContext().lookup("java:comp/env");
            String value = (String) env.lookup("HUDSON_HOME");
            if(value!=null && value.trim().length()>0)
                return new File(value.trim()).getAbsoluteFile();
        } catch (NamingException e) {
            // ignore
        }

        // look at the env var next
        String env = EnvVars.masterEnvVars.get("HUDSON_HOME");
        if(env!=null)
            return new File(env.trim()).getAbsoluteFile();

        // finally check the system property
        String sysProp = System.getProperty("HUDSON_HOME");
        if(sysProp!=null)
            return new File(sysProp.trim()).getAbsoluteFile();

        // otherwise pick a place by ourselves

        String root = event.getServletContext().getRealPath("/WEB-INF/workspace");
        if(root!=null) {
            File ws = new File(root.trim());
            if(ws.exists())
                // Hudson <1.42 used to prefer this betfore ~/.hudson, so
                // check the existence and if it's there, use it.
                // otherwise if this is a new installation, prefer ~/.hudson
                return ws.getAbsoluteFile();
        }

        // if for some reason we can't put it within the webapp, use home directory.
        return new File(new File(System.getProperty("user.home")),".hudson").getAbsoluteFile();
    }

    public void contextDestroyed(ServletContextEvent event) {
        Hudson instance = Hudson.getInstance();
        if(instance!=null)
            instance.cleanUp();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy