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();
}
}