protected Jenkins()

in core/src/main/java/jenkins/model/Jenkins.java [861:1032]


    protected Jenkins(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException {
        oldJenkinsJVM = JenkinsJVM.isJenkinsJVM(); // capture to restore in cleanUp()
        JenkinsJVMAccess._setJenkinsJVM(true); // set it for unit tests as they will not have gone through WebAppMain
        long start = System.currentTimeMillis();
        STARTUP_MARKER_FILE = new FileBoolean(new File(root, ".lastStarted"));
        // As Jenkins is starting, grant this process full control
        try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
            this.root = root;
            this.servletContext = context;
            computeVersion(context);
            if(theInstance!=null)
                throw new IllegalStateException("second instance");
            theInstance = this;

            if (!new File(root,"jobs").exists()) {
                // if this is a fresh install, use more modern default layout that's consistent with agents
                workspaceDir = DEFAULT_WORKSPACES_DIR;
            }

            // doing this early allows InitStrategy to set environment upfront
            //Telemetry: add interceptor classloader
            //These lines allow the catcher to be present on Thread.currentThread().getContextClassLoader() in every plugin which
            //allow us to detect failures in every plugin loading classes by this way.
            if (MissingClassTelemetry.enabled() && !(Thread.currentThread().getContextClassLoader() instanceof CatcherClassLoader)) {
                Thread.currentThread().setContextClassLoader(new CatcherClassLoader(Thread.currentThread().getContextClassLoader()));
            }
            final InitStrategy is = InitStrategy.get(Thread.currentThread().getContextClassLoader());

            Trigger.timer = new java.util.Timer("Jenkins cron thread");
            queue = new Queue(LoadBalancer.CONSISTENT_HASH);

            try {
                dependencyGraph = DependencyGraph.EMPTY;
            } catch (InternalError e) {
                if(e.getMessage().contains("window server")) {
                    throw new Error("Looks like the server runs without X. Please specify -Djava.awt.headless=true as JVM option",e);
                }
                throw e;
            }

            // get or create the secret
            TextFile secretFile = new TextFile(new File(getRootDir(),"secret.key"));
            if(secretFile.exists()) {
                secretKey = secretFile.readTrim();
            } else {
                SecureRandom sr = new SecureRandom();
                byte[] random = new byte[32];
                sr.nextBytes(random);
                secretKey = Util.toHexString(random);
                secretFile.write(secretKey);

                // this marker indicates that the secret.key is generated by the version of Jenkins post SECURITY-49.
                // this indicates that there's no need to rewrite secrets on disk
                new FileBoolean(new File(root,"secret.key.not-so-secret")).on();
            }

            try {
                proxy = ProxyConfiguration.load();
            } catch (IOException e) {
                LOGGER.log(SEVERE, "Failed to load proxy configuration", e);
            }

            if (pluginManager==null)
                pluginManager = PluginManager.createDefault(this);
            this.pluginManager = pluginManager;
            WebApp webApp = WebApp.get(servletContext);

            //Telemetry: add interceptor classloader
            //These lines allows the catcher to be present on Thread.currentThread().getContextClassLoader() in every plugin which
            //allow us to detect failures in every plugin loading classes by this way.
            // JSON binding needs to be able to see all the classes from all the plugins

            ClassLoader classLoaderToAssign;
            if (MissingClassTelemetry.enabled() && !(pluginManager.uberClassLoader instanceof CatcherClassLoader)) {
                classLoaderToAssign = new CatcherClassLoader(pluginManager.uberClassLoader);
            } else {
                classLoaderToAssign = pluginManager.uberClassLoader;
            }
            webApp.setClassLoader(classLoaderToAssign);

            webApp.setJsonInErrorMessageSanitizer(RedactSecretJsonInErrorMessageSanitizer.INSTANCE);

            TypedFilter typedFilter = new TypedFilter();
            webApp.setFilterForGetMethods(typedFilter);
            webApp.setFilterForFields(typedFilter);
            webApp.setFilterForDoActions(new DoActionFilter());

            StaplerFilteredActionListener actionListener = new StaplerFilteredActionListener();
            webApp.setFilteredGetterTriggerListener(actionListener);
            webApp.setFilteredDoActionTriggerListener(actionListener);
            webApp.setFilteredFieldTriggerListener(actionListener);

            webApp.setDispatchValidator(new StaplerDispatchValidator());
            webApp.setFilteredDispatchTriggerListener(actionListener);

            //Telemetry: add interceptor classloader
            //These lines allows the catcher to be present on Thread.currentThread().getContextClassLoader() in every plugin which
            //allow us to detect failures in every plugin loading classes at this way.
            adjuncts = new AdjunctManager(servletContext, classLoaderToAssign, "adjuncts/" + SESSION_HASH, TimeUnit.DAYS.toMillis(365));

            ClassFilterImpl.register();

            // initialization consists of ...
            executeReactor( is,
                    pluginManager.initTasks(is),    // loading and preparing plugins
                    loadTasks(),                    // load jobs
                    InitMilestone.ordering()        // forced ordering among key milestones
            );

            // Ensure we reached the final initialization state. Log the error otherwise
            if (initLevel != InitMilestone.COMPLETED) {
                LOGGER.log(SEVERE, "Jenkins initialization has not reached the COMPLETED initialization milestone after the startup. " +
                                "Current state: {0}. " +
                                "It may cause undefined incorrect behavior in Jenkins plugin relying on this state. " +
                                "It is likely an issue with the Initialization task graph. " +
                                "Example: usage of @Initializer(after = InitMilestone.COMPLETED) in a plugin (JENKINS-37759). " +
                                "Please create a bug in Jenkins bugtracker. ",
                        initLevel);
            }


            if(KILL_AFTER_LOAD)
                // TODO cleanUp?
                System.exit(0);
            save();

            launchTcpSlaveAgentListener();

            Timer.get().scheduleAtFixedRate(new SafeTimerTask() {
                @Override
                protected void doRun() throws Exception {
                    trimLabels();
                }
            }, TimeUnit.MINUTES.toMillis(5), TimeUnit.MINUTES.toMillis(5), TimeUnit.MILLISECONDS);

            updateComputerList();

            {// master is online now, it's instance must always exist
                final Computer c = toComputer();
                if(c != null) {
                    for (ComputerListener cl : ComputerListener.all()) {
                        try {
                            cl.onOnline(c, new LogTaskListener(LOGGER, INFO));
                        } catch (Exception e) {
                            // Per Javadoc log exceptions but still go online.
                            // NOTE: this does not include Errors, which indicate a fatal problem
                            LOGGER.log(WARNING, String.format("Exception in onOnline() for the computer listener %s on the Jenkins master node",
                                    cl.getClass()), e);
                        }
                    }
                }
            }

            for (ItemListener l : ItemListener.all()) {
                long itemListenerStart = System.currentTimeMillis();
                try {
                    l.onLoaded();
                } catch (RuntimeException x) {
                    LOGGER.log(Level.WARNING, null, x);
                }
                if (LOG_STARTUP_PERFORMANCE)
                    LOGGER.info(String.format("Took %dms for item listener %s startup",
                            System.currentTimeMillis()-itemListenerStart,l.getClass().getName()));
            }

            if (LOG_STARTUP_PERFORMANCE)
                LOGGER.info(String.format("Took %dms for complete Jenkins startup",
                        System.currentTimeMillis()-start));

            STARTUP_MARKER_FILE.on();
        }
    }