]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4843 restart most of components
authorSimon Brandhof <simon.brandhof@gmail.com>
Sun, 16 Mar 2014 22:31:18 +0000 (23:31 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Sun, 16 Mar 2014 22:31:18 +0000 (23:31 +0100)
sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentContainer.java
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java [deleted file]
sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java
sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
sonar-server/src/test/java/org/sonar/server/platform/ws/RestartHandlerTest.java

index ec001e31d788ced150e46762afda42e17d911b3a..ac26bc0052122c06832104d0b24ea0fe4bf900bd 100644 (file)
@@ -32,7 +32,7 @@ import org.sonar.api.ServerComponent;
 import org.sonar.api.config.PropertyDefinitions;
 
 import javax.annotation.Nullable;
-
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -152,6 +152,13 @@ public class ComponentContainer implements BatchComponent, ServerComponent {
     return this;
   }
 
+  public ComponentContainer addSingletons(Collection components) {
+    for (Object component : components) {
+      addSingleton(component);
+    }
+    return this;
+  }
+
   public ComponentContainer addSingleton(Object component) {
     return addComponent(component, true);
   }
@@ -162,8 +169,12 @@ public class ComponentContainer implements BatchComponent, ServerComponent {
    */
   public ComponentContainer addComponent(Object component, boolean singleton) {
     Object key = componentKeys.of(component);
-    pico.as(singleton ? Characteristics.CACHE : Characteristics.NO_CACHE).addComponent(key, component);
-    declareExtension(null, component);
+    if (component instanceof ComponentAdapter) {
+      pico.addAdapter((ComponentAdapter) component);
+    } else {
+      pico.as(singleton ? Characteristics.CACHE : Characteristics.NO_CACHE).addComponent(key, component);
+      declareExtension(null, component);
+    }
     return this;
   }
 
index ea7ad0bc995150f08cc3a3a3250991763b11d611..353893e7d0bf90abc70087769fcfa364d03924dd 100644 (file)
  */
 package org.sonar.server.platform;
 
-import org.apache.commons.configuration.BaseConfiguration;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.platform.Server;
-import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.HttpDownloader;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.api.utils.UriReader;
-import org.sonar.api.utils.internal.TempFolderCleaner;
-import org.sonar.core.config.Logback;
-import org.sonar.core.i18n.DefaultI18n;
-import org.sonar.core.i18n.GwtI18n;
-import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.persistence.DaoUtils;
 import org.sonar.core.persistence.DatabaseVersion;
-import org.sonar.core.persistence.DefaultDatabase;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.persistence.PreviewDatabaseFactory;
-import org.sonar.core.persistence.SemaphoreUpdater;
-import org.sonar.core.persistence.SemaphoresImpl;
-import org.sonar.core.profiling.Profiling;
-import org.sonar.core.purge.PurgeProfiler;
-import org.sonar.jpa.session.DatabaseSessionProvider;
-import org.sonar.jpa.session.DefaultDatabaseConnector;
-import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
-import org.sonar.server.db.EmbeddedDatabaseFactory;
-import org.sonar.server.db.migrations.DatabaseMigration;
-import org.sonar.server.db.migrations.DatabaseMigrations;
-import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.es.ESNode;
-import org.sonar.server.platform.ws.PlatformWs;
-import org.sonar.server.platform.ws.RestartHandler;
-import org.sonar.server.plugins.ServerPluginJarInstaller;
-import org.sonar.server.plugins.ServerPluginJarsInstaller;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.startup.ServerMetadataPersister;
-import org.sonar.server.ui.JRubyI18n;
-import org.sonar.server.ui.JRubyProfiling;
 
 import javax.annotation.CheckForNull;
 import javax.servlet.ServletContext;
@@ -70,12 +34,10 @@ public class Platform {
 
   private static final Platform INSTANCE = new Platform();
 
-  // level 1 : database stuff, settings
-  // level 2 : level 1 + components that are never restarted
-  // level 3 : level 2 + all other components, including plugin extensions
-  private ComponentContainer level1Container, level2Container, level3Container;
-
-  private boolean connected = false;
+  private ServerComponents serverComponents;
+  private ComponentContainer level1Container, level2Container, level3Container, level4Container;
+  private ComponentContainer currentContainer;
+  private boolean dbConnected = false;
   private boolean started = false;
 
   private Platform() {
@@ -104,98 +66,70 @@ public class Platform {
   }
 
   public void init(ServletContext servletContext) {
-    if (!connected) {
-      startLevel1Container(servletContext);
-      connected = true;
+    serverComponents = new ServerComponents(this, servletContext);
+    if (!dbConnected) {
+      startLevel1Container();
+      startLevel2Container();
+      dbConnected = true;
     }
   }
 
-  // Platform is injected in Pico, so do not rename "start"
+  // Platform is injected in Pico, so do not rename this method "start"
   public void doStart() {
     if (!started && getDatabaseStatus() == DatabaseVersion.Status.UP_TO_DATE) {
-      TimeProfiler profiler = new TimeProfiler().start("Start components");
-      startLevel2Container();
+      startLevel34Containers();
       started = true;
-      profiler.stop();
     }
   }
 
-  private void startLevel1Container(ServletContext servletContext) {
+  /**
+   * Start level 1 only
+   */
+  private void startLevel1Container() {
     level1Container = new ComponentContainer();
-    level1Container.addSingleton(this);
-    level1Container.addSingleton(servletContext);
-    level1Container.addSingleton(new BaseConfiguration());
-    level1Container.addSingleton(ServerSettings.class);
-    level1Container.addSingleton(ServerImpl.class);
-    level1Container.addSingleton(Logback.class);
-    level1Container.addSingleton(Profiling.class);
-    level1Container.addSingleton(JRubyProfiling.class);
-    level1Container.addSingleton(EmbeddedDatabaseFactory.class);
-    level1Container.addSingleton(DefaultDatabase.class);
-    level1Container.addSingleton(MyBatis.class);
-    level1Container.addSingleton(DefaultServerUpgradeStatus.class);
-    level1Container.addSingleton(DatabaseServerCompatibility.class);
-    for (Class<? extends DatabaseMigration> migrationClass : DatabaseMigrations.CLASSES) {
-      level1Container.addSingleton(migrationClass);
-    }
-    level1Container.addSingleton(DatabaseMigrator.class);
-    level1Container.addSingleton(DatabaseVersion.class);
-    for (Class daoClass : DaoUtils.getDaoClasses()) {
-      level1Container.addSingleton(daoClass);
-    }
-    level1Container.addSingleton(PurgeProfiler.class);
-    level1Container.addSingleton(DefaultServerFileSystem.class);
-    level1Container.addSingleton(PreviewDatabaseFactory.class);
-    level1Container.addSingleton(SemaphoreUpdater.class);
-    level1Container.addSingleton(SemaphoresImpl.class);
-    level1Container.addPicoAdapter(new TempFolderProvider());
-    level1Container.addSingleton(TempFolderCleaner.class);
-
-
-    // plugins
-    level1Container.addSingleton(ServerPluginJarsInstaller.class);
-    level1Container.addSingleton(ServerPluginJarInstaller.class);
-    level1Container.addSingleton(InstalledPluginReferentialFactory.class);
-    level1Container.addSingleton(ServerPluginRepository.class);
-    level1Container.addSingleton(ServerExtensionInstaller.class);
-
-    // depends on plugins
-    level1Container.addSingleton(RailsAppsDeployer.class);
-    level1Container.addSingleton(JRubyI18n.class);
-    level1Container.addSingleton(DefaultI18n.class);
-    level1Container.addSingleton(RuleI18nManager.class);
-    level1Container.addSingleton(GwtI18n.class);
-    level1Container.addSingleton(Durations.class);
+    level1Container.addSingletons(serverComponents.level1Components());
     level1Container.startComponents();
-  }
-
-  private DatabaseVersion.Status getDatabaseStatus() {
-    DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
-    return version.getStatus();
+    currentContainer = level1Container;
   }
 
   /**
-   * Components listed here are never restarted
+   * Start level 2 only
    */
   private void startLevel2Container() {
     level2Container = level1Container.createChild();
-    level2Container.addSingleton(PersistentSettings.class);
-    level2Container.addSingleton(DefaultDatabaseConnector.class);
-    level2Container.addSingleton(ThreadLocalDatabaseSessionFactory.class);
-    level2Container.addPicoAdapter(new DatabaseSessionProvider());
-    level2Container.addSingleton(ServerMetadataPersister.class);
-    level2Container.addSingleton(ESNode.class);
-    level2Container.addSingleton(HttpDownloader.class);
-    level2Container.addSingleton(UriReader.class);
-    level2Container.addSingleton(ServerIdGenerator.class);
-
-    // ws
-    level2Container.addSingleton(RestartHandler.class);
-    level2Container.addSingleton(PlatformWs.class);
-
+    level2Container.addSingletons(serverComponents.level2Components());
     level2Container.startComponents();
+    currentContainer = level2Container;
+  }
+
+  /**
+   * Start level 3 and greater
+   */
+  private void startLevel34Containers() {
+    level3Container = level2Container.createChild();
+    level3Container.addSingletons(serverComponents.level3Components());
+    level3Container.startComponents();
+    currentContainer = level3Container;
 
-    restartLevel3Container();
+    level4Container = level3Container.createChild();
+    serverComponents.startLevel4Components(level4Container);
+    currentContainer = level4Container;
+
+  }
+
+  public void restart() {
+    // Do not need to initialize database connection, so level 1 is skipped
+    if (level2Container != null) {
+      level2Container.stopComponents();
+      currentContainer = level1Container;
+    }
+    startLevel2Container();
+    startLevel34Containers();
+  }
+
+  private DatabaseVersion.Status getDatabaseStatus() {
+    DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
+    return version.getStatus();
   }
 
   // Do not rename "stop"
@@ -204,7 +138,8 @@ public class Platform {
       try {
         level1Container.stopComponents();
         level1Container = null;
-        connected = false;
+        currentContainer = null;
+        dbConnected = false;
         started = false;
       } catch (Exception e) {
         LoggerFactory.getLogger(getClass()).debug("Fail to stop server - ignored", e);
@@ -212,22 +147,8 @@ public class Platform {
     }
   }
 
-  public void restartLevel3Container() {
-    if (level3Container != null) {
-      level3Container.stopComponents();
-    }
-    level3Container = level2Container.createChild();
-    new ServerComponentsStarter().start(level3Container);
-  }
-
   public ComponentContainer getContainer() {
-    if (level3Container != null) {
-      return level3Container;
-    }
-    if (level2Container != null) {
-      return level2Container;
-    }
-    return level1Container;
+    return currentContainer;
   }
 
   public Object getComponent(Object key) {
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
new file mode 100644 (file)
index 0000000..5575413
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.configuration.BaseConfiguration;
+import org.sonar.api.config.EmailSettings;
+import org.sonar.api.issue.action.Actions;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.api.profiles.AnnotationProfileParser;
+import org.sonar.api.profiles.XMLProfileParser;
+import org.sonar.api.profiles.XMLProfileSerializer;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.rules.AnnotationRuleParser;
+import org.sonar.api.rules.XMLRuleParser;
+import org.sonar.api.utils.Durations;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.api.utils.UriReader;
+import org.sonar.api.utils.internal.TempFolderCleaner;
+import org.sonar.core.component.SnapshotPerspectives;
+import org.sonar.core.component.db.ComponentDao;
+import org.sonar.core.config.Logback;
+import org.sonar.core.i18n.DefaultI18n;
+import org.sonar.core.i18n.GwtI18n;
+import org.sonar.core.i18n.RuleI18nManager;
+import org.sonar.core.issue.IssueFilterSerializer;
+import org.sonar.core.issue.IssueNotifications;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.workflow.FunctionExecutor;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.measure.MeasureFilterEngine;
+import org.sonar.core.measure.MeasureFilterExecutor;
+import org.sonar.core.measure.MeasureFilterFactory;
+import org.sonar.core.metric.DefaultMetricFinder;
+import org.sonar.core.notification.DefaultNotificationManager;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.preview.PreviewCache;
+import org.sonar.core.profiling.Profiling;
+import org.sonar.core.purge.PurgeProfiler;
+import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
+import org.sonar.core.qualitygate.db.QualityGateDao;
+import org.sonar.core.resource.DefaultResourcePermissions;
+import org.sonar.core.rule.DefaultRuleFinder;
+import org.sonar.core.technicaldebt.DefaultTechnicalDebtManager;
+import org.sonar.core.technicaldebt.TechnicalDebtModelRepository;
+import org.sonar.core.technicaldebt.TechnicalDebtModelSynchronizer;
+import org.sonar.core.technicaldebt.TechnicalDebtXMLImporter;
+import org.sonar.core.test.TestPlanPerspectiveLoader;
+import org.sonar.core.test.TestablePerspectiveLoader;
+import org.sonar.core.timemachine.Periods;
+import org.sonar.core.user.DefaultUserFinder;
+import org.sonar.core.user.HibernateUserFinder;
+import org.sonar.jpa.dao.MeasuresDao;
+import org.sonar.jpa.dao.ProfilesDao;
+import org.sonar.jpa.dao.RulesDao;
+import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.jpa.session.DatabaseSessionProvider;
+import org.sonar.jpa.session.DefaultDatabaseConnector;
+import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
+import org.sonar.server.charts.ChartFactory;
+import org.sonar.server.component.DefaultComponentFinder;
+import org.sonar.server.component.DefaultRubyComponentService;
+import org.sonar.server.db.EmbeddedDatabaseFactory;
+import org.sonar.server.db.migrations.DatabaseMigrations;
+import org.sonar.server.db.migrations.DatabaseMigrator;
+import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
+import org.sonar.server.debt.DebtModelSynchronizer;
+import org.sonar.server.debt.DebtRulesXMLImporter;
+import org.sonar.server.debt.DebtService;
+import org.sonar.server.es.ESIndex;
+import org.sonar.server.es.ESNode;
+import org.sonar.server.issue.ActionPlanService;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.DefaultIssueFinder;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogFormatter;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.IssueStatsFinder;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.PublicRubyIssueService;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
+import org.sonar.server.issue.filter.IssueFilterService;
+import org.sonar.server.issue.filter.IssueFilterWs;
+import org.sonar.server.issue.ws.IssueShowWsHandler;
+import org.sonar.server.issue.ws.IssuesWs;
+import org.sonar.server.notifications.NotificationCenter;
+import org.sonar.server.notifications.NotificationService;
+import org.sonar.server.permission.InternalPermissionService;
+import org.sonar.server.permission.InternalPermissionTemplateService;
+import org.sonar.server.permission.PermissionFinder;
+import org.sonar.server.platform.ws.PlatformWs;
+import org.sonar.server.platform.ws.RestartHandler;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginJarInstaller;
+import org.sonar.server.plugins.ServerPluginJarsInstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.qualitygate.QgateProjectFinder;
+import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.qualitygate.ws.QgateAppHandler;
+import org.sonar.server.qualitygate.ws.QualityGatesWs;
+import org.sonar.server.qualityprofile.ESActiveRule;
+import org.sonar.server.qualityprofile.ProfilesManager;
+import org.sonar.server.qualityprofile.QProfileActiveRuleOperations;
+import org.sonar.server.qualityprofile.QProfileBackup;
+import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.QProfileOperations;
+import org.sonar.server.qualityprofile.QProfileProjectLookup;
+import org.sonar.server.qualityprofile.QProfileProjectOperations;
+import org.sonar.server.qualityprofile.QProfileRepositoryExporter;
+import org.sonar.server.qualityprofile.QProfileRuleLookup;
+import org.sonar.server.qualityprofile.QProfiles;
+import org.sonar.server.rule.DeprecatedRulesDefinition;
+import org.sonar.server.rule.ESRuleTags;
+import org.sonar.server.rule.RubyRuleService;
+import org.sonar.server.rule.RuleDefinitionsLoader;
+import org.sonar.server.rule.RuleOperations;
+import org.sonar.server.rule.RuleRegistration;
+import org.sonar.server.rule.RuleRegistry;
+import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.rule.RuleTagLookup;
+import org.sonar.server.rule.RuleTagOperations;
+import org.sonar.server.rule.RuleTags;
+import org.sonar.server.rule.Rules;
+import org.sonar.server.rule.ws.AddTagsWsHandler;
+import org.sonar.server.rule.ws.RemoveTagsWsHandler;
+import org.sonar.server.rule.ws.RuleSearchWsHandler;
+import org.sonar.server.rule.ws.RuleShowWsHandler;
+import org.sonar.server.rule.ws.RuleTagsWs;
+import org.sonar.server.rule.ws.RulesWs;
+import org.sonar.server.source.CodeColorizers;
+import org.sonar.server.source.DeprecatedSourceDecorator;
+import org.sonar.server.source.HtmlSourceDecorator;
+import org.sonar.server.source.SourceService;
+import org.sonar.server.source.ws.SourcesShowWsHandler;
+import org.sonar.server.source.ws.SourcesWs;
+import org.sonar.server.startup.CleanPreviewAnalysisCache;
+import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
+import org.sonar.server.startup.GenerateBootstrapIndex;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.GwtPublisher;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterDebtModel;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewDashboards;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterNewProfiles;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.text.MacroInterpreter;
+import org.sonar.server.text.RubyTextService;
+import org.sonar.server.ui.JRubyI18n;
+import org.sonar.server.ui.JRubyProfiling;
+import org.sonar.server.ui.PageDecorations;
+import org.sonar.server.ui.Views;
+import org.sonar.server.user.DefaultUserService;
+import org.sonar.server.user.GroupMembershipFinder;
+import org.sonar.server.user.GroupMembershipService;
+import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.user.SecurityRealmFactory;
+import org.sonar.server.util.BooleanTypeValidation;
+import org.sonar.server.util.FloatTypeValidation;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringListTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TextTypeValidation;
+import org.sonar.server.util.TypeValidations;
+import org.sonar.server.ws.ListingWs;
+import org.sonar.server.ws.WebServiceEngine;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+class ServerComponents {
+
+  private final Object[] rootComponents;
+
+  ServerComponents(Object... rootComponents) {
+    this.rootComponents = rootComponents;
+  }
+
+  /**
+   * All the stuff required to connect to database
+   */
+  Collection level1Components() {
+    List components = Lists.newArrayList(rootComponents);
+    components.addAll(Arrays.asList(
+      new BaseConfiguration(),
+      ServerSettings.class,
+      ServerImpl.class,
+      Logback.class,
+      Profiling.class,
+      JRubyProfiling.class,
+      EmbeddedDatabaseFactory.class,
+      DefaultDatabase.class,
+      MyBatis.class,
+      DefaultServerUpgradeStatus.class,
+      DatabaseServerCompatibility.class,
+      DatabaseMigrator.class,
+      DatabaseVersion.class,
+      PurgeProfiler.class,
+      DefaultServerFileSystem.class,
+      PreviewDatabaseFactory.class,
+      SemaphoreUpdater.class,
+      SemaphoresImpl.class,
+      TempFolderCleaner.class,
+      new TempFolderProvider()
+    ));
+    components.addAll(DatabaseMigrations.CLASSES);
+    components.addAll(DaoUtils.getDaoClasses());
+    return components;
+  }
+
+  /**
+   * The stuff required to display the db upgrade form in webapp.
+   * Needs to be connected to db.
+   */
+  Collection level2Components() {
+    return Lists.newArrayList(
+      // plugins
+      ServerPluginJarsInstaller.class,
+      ServerPluginJarInstaller.class,
+      InstalledPluginReferentialFactory.class,
+      ServerPluginRepository.class,
+      ServerExtensionInstaller.class,
+
+      // depends on plugins
+      RailsAppsDeployer.class,
+      JRubyI18n.class,
+      DefaultI18n.class,
+      RuleI18nManager.class,
+      GwtI18n.class,
+      Durations.class,
+
+      // ws
+      RestartHandler.class,
+      PlatformWs.class
+    );
+  }
+
+  /**
+   * The core components that complete the initialization of database
+   * when its schema is up-to-date.
+   */
+  Collection level3Components() {
+    return Lists.newArrayList(
+      PersistentSettings.class,
+      DefaultDatabaseConnector.class,
+      ThreadLocalDatabaseSessionFactory.class,
+      new DatabaseSessionProvider(),
+      ServerMetadataPersister.class,
+      ESNode.class,
+      HttpDownloader.class,
+      UriReader.class,
+      ServerIdGenerator.class
+    );
+  }
+
+
+  void startLevel4Components(ComponentContainer pico) {
+    pico.addSingleton(ESIndex.class);
+    pico.addSingleton(UpdateCenterClient.class);
+    pico.addSingleton(UpdateCenterMatrixFactory.class);
+    pico.addSingleton(PluginDownloader.class);
+    pico.addSingleton(ChartFactory.class);
+    pico.addSingleton(Languages.class);
+    pico.addSingleton(Views.class);
+    pico.addSingleton(CodeColorizers.class);
+    pico.addSingleton(ResourceTypes.class);
+    pico.addSingleton(SettingsChangeNotifier.class);
+    pico.addSingleton(PageDecorations.class);
+    pico.addSingleton(PreviewCache.class);
+    pico.addSingleton(DefaultResourcePermissions.class);
+    pico.addSingleton(Periods.class);
+
+    // quality profile
+    pico.addSingleton(XMLProfileParser.class);
+    pico.addSingleton(XMLProfileSerializer.class);
+    pico.addComponent(ProfilesDao.class, false);
+    pico.addComponent(ProfilesManager.class, false);
+    pico.addSingleton(AnnotationProfileParser.class);
+    pico.addSingleton(QProfileRuleLookup.class);
+    pico.addSingleton(QProfiles.class);
+    pico.addSingleton(QProfileLookup.class);
+    pico.addSingleton(QProfileOperations.class);
+    pico.addSingleton(QProfileActiveRuleOperations.class);
+    pico.addSingleton(QProfileProjectOperations.class);
+    pico.addSingleton(QProfileProjectLookup.class);
+    pico.addSingleton(QProfileBackup.class);
+    pico.addSingleton(QProfileRepositoryExporter.class);
+    pico.addSingleton(ESActiveRule.class);
+
+    // rule
+    pico.addSingleton(AnnotationRuleParser.class);
+    pico.addSingleton(XMLRuleParser.class);
+    pico.addComponent(RulesDao.class, false);
+    pico.addSingleton(DefaultRuleFinder.class);
+    pico.addSingleton(Rules.class);
+    pico.addSingleton(RuleOperations.class);
+    pico.addSingleton(RuleRegistry.class);
+    pico.addSingleton(RubyRuleService.class);
+    pico.addSingleton(RuleRepositories.class);
+    pico.addSingleton(RulesWs.class);
+    pico.addSingleton(RuleShowWsHandler.class);
+    pico.addSingleton(RuleSearchWsHandler.class);
+    pico.addSingleton(AddTagsWsHandler.class);
+    pico.addSingleton(RemoveTagsWsHandler.class);
+
+    // rule tags
+    pico.addSingleton(ESRuleTags.class);
+    pico.addSingleton(RuleTagLookup.class);
+    pico.addSingleton(RuleTagOperations.class);
+    pico.addSingleton(RuleTags.class);
+    pico.addSingleton(RuleTagsWs.class);
+
+    // measure
+    pico.addComponent(MeasuresDao.class, false);
+    pico.addSingleton(MeasureFilterFactory.class);
+    pico.addSingleton(MeasureFilterExecutor.class);
+    pico.addSingleton(MeasureFilterEngine.class);
+    pico.addSingleton(DefaultMetricFinder.class);
+    pico.addSingleton(ServerLifecycleNotifier.class);
+
+    // quality gates
+    pico.addSingleton(QualityGateDao.class);
+    pico.addSingleton(QualityGateConditionDao.class);
+    pico.addSingleton(QualityGates.class);
+    pico.addSingleton(ProjectQgateAssociationDao.class);
+    pico.addSingleton(QgateProjectFinder.class);
+    pico.addSingleton(QgateAppHandler.class);
+    pico.addSingleton(QualityGatesWs.class);
+
+    // web services
+    pico.addSingleton(WebServiceEngine.class);
+    pico.addSingleton(ListingWs.class);
+
+    // users
+    pico.addSingleton(SecurityRealmFactory.class);
+    pico.addSingleton(HibernateUserFinder.class);
+    pico.addSingleton(NewUserNotifier.class);
+    pico.addSingleton(DefaultUserFinder.class);
+    pico.addSingleton(DefaultUserService.class);
+
+    // groups
+    pico.addSingleton(GroupMembershipService.class);
+    pico.addSingleton(GroupMembershipFinder.class);
+
+    // permissions
+    pico.addSingleton(PermissionFacade.class);
+    pico.addSingleton(InternalPermissionService.class);
+    pico.addSingleton(InternalPermissionTemplateService.class);
+    pico.addSingleton(PermissionFinder.class);
+
+    // components
+    pico.addSingleton(DefaultComponentFinder.class);
+    pico.addSingleton(DefaultRubyComponentService.class);
+    pico.addSingleton(ComponentDao.class);
+
+    // issues
+    pico.addSingleton(ServerIssueStorage.class);
+    pico.addSingleton(IssueUpdater.class);
+    pico.addSingleton(FunctionExecutor.class);
+    pico.addSingleton(IssueWorkflow.class);
+    pico.addSingleton(IssueService.class);
+    pico.addSingleton(IssueCommentService.class);
+    pico.addSingleton(DefaultIssueFinder.class);
+    pico.addSingleton(IssueStatsFinder.class);
+    pico.addSingleton(PublicRubyIssueService.class);
+    pico.addSingleton(InternalRubyIssueService.class);
+    pico.addSingleton(ActionPlanService.class);
+    pico.addSingleton(IssueChangelogService.class);
+    pico.addSingleton(IssueNotifications.class);
+    pico.addSingleton(ActionService.class);
+    pico.addSingleton(Actions.class);
+    pico.addSingleton(IssueFilterSerializer.class);
+    pico.addSingleton(IssueFilterService.class);
+    pico.addSingleton(IssueBulkChangeService.class);
+    pico.addSingleton(IssueChangelogFormatter.class);
+    pico.addSingleton(IssueFilterWs.class);
+    pico.addSingleton(IssueShowWsHandler.class);
+    pico.addSingleton(IssuesWs.class);
+
+    // issues actions
+    pico.addSingleton(AssignAction.class);
+    pico.addSingleton(PlanAction.class);
+    pico.addSingleton(SetSeverityAction.class);
+    pico.addSingleton(CommentAction.class);
+    pico.addSingleton(TransitionAction.class);
+
+    // technical debt
+    pico.addSingleton(DebtService.class);
+    pico.addSingleton(TechnicalDebtModelSynchronizer.class);
+    pico.addSingleton(DebtModelSynchronizer.class);
+    pico.addSingleton(TechnicalDebtModelRepository.class);
+    pico.addSingleton(TechnicalDebtXMLImporter.class);
+    pico.addSingleton(DebtRulesXMLImporter.class);
+    pico.addSingleton(DebtCharacteristicsXMLImporter.class);
+    pico.addSingleton(DefaultTechnicalDebtManager.class);
+
+    // source
+    pico.addSingleton(HtmlSourceDecorator.class);
+    pico.addSingleton(DeprecatedSourceDecorator.class);
+    pico.addSingleton(SourceService.class);
+    pico.addSingleton(SourcesWs.class);
+    pico.addSingleton(SourcesShowWsHandler.class);
+
+    // text
+    pico.addSingleton(MacroInterpreter.class);
+    pico.addSingleton(RubyTextService.class);
+
+    // Notifications
+    pico.addSingleton(EmailSettings.class);
+    pico.addSingleton(NotificationService.class);
+    pico.addSingleton(NotificationCenter.class);
+    pico.addSingleton(DefaultNotificationManager.class);
+
+    // graphs and perspective related classes
+    pico.addSingleton(TestablePerspectiveLoader.class);
+    pico.addSingleton(TestPlanPerspectiveLoader.class);
+    pico.addSingleton(SnapshotPerspectives.class);
+
+    // Type validation
+    pico.addSingleton(TypeValidations.class);
+    pico.addSingleton(IntegerTypeValidation.class);
+    pico.addSingleton(FloatTypeValidation.class);
+    pico.addSingleton(BooleanTypeValidation.class);
+    pico.addSingleton(TextTypeValidation.class);
+    pico.addSingleton(StringTypeValidation.class);
+    pico.addSingleton(StringListTypeValidation.class);
+
+    ServerExtensionInstaller extensionRegistrar = pico.getComponentByType(ServerExtensionInstaller.class);
+    extensionRegistrar.installExtensions(pico);
+
+    pico.startComponents();
+    executeStartupTaks(pico);
+  }
+
+  private void executeStartupTaks(ComponentContainer pico) {
+    ComponentContainer startupContainer = pico.createChild();
+    startupContainer.addSingleton(GwtPublisher.class);
+    startupContainer.addSingleton(RegisterMetrics.class);
+    startupContainer.addSingleton(DeprecatedRulesDefinition.class);
+    startupContainer.addSingleton(RuleDefinitionsLoader.class);
+    startupContainer.addSingleton(RuleRegistration.class);
+    startupContainer.addSingleton(RegisterNewProfiles.class);
+    startupContainer.addSingleton(JdbcDriverDeployer.class);
+    startupContainer.addSingleton(RegisterDebtModel.class);
+    startupContainer.addSingleton(GeneratePluginIndex.class);
+    startupContainer.addSingleton(GenerateBootstrapIndex.class);
+    startupContainer.addSingleton(RegisterNewMeasureFilters.class);
+    startupContainer.addSingleton(RegisterNewDashboards.class);
+    startupContainer.addSingleton(RegisterPermissionTemplates.class);
+    startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
+    startupContainer.addSingleton(LogServerId.class);
+    startupContainer.addSingleton(RegisterServletFilters.class);
+    startupContainer.addSingleton(CleanPreviewAnalysisCache.class);
+    startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class);
+    startupContainer.startComponents();
+
+    startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart();
+
+    // Do not put the following statements in a finally block.
+    // It would hide the possible exception raised during startup
+    // See SONAR-3107
+    startupContainer.stopComponents();
+    pico.getComponentByType(DatabaseSessionFactory.class).clear();
+  }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java
deleted file mode 100644 (file)
index c360d94..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.platform;
-
-import org.sonar.api.config.EmailSettings;
-import org.sonar.api.issue.action.Actions;
-import org.sonar.api.platform.ComponentContainer;
-import org.sonar.api.profiles.AnnotationProfileParser;
-import org.sonar.api.profiles.XMLProfileParser;
-import org.sonar.api.profiles.XMLProfileSerializer;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.rules.AnnotationRuleParser;
-import org.sonar.api.rules.XMLRuleParser;
-import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.component.db.ComponentDao;
-import org.sonar.core.issue.IssueFilterSerializer;
-import org.sonar.core.issue.IssueNotifications;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.workflow.FunctionExecutor;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.core.measure.MeasureFilterEngine;
-import org.sonar.core.measure.MeasureFilterExecutor;
-import org.sonar.core.measure.MeasureFilterFactory;
-import org.sonar.core.metric.DefaultMetricFinder;
-import org.sonar.core.notification.DefaultNotificationManager;
-import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.preview.PreviewCache;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
-import org.sonar.core.qualitygate.db.QualityGateConditionDao;
-import org.sonar.core.qualitygate.db.QualityGateDao;
-import org.sonar.core.resource.DefaultResourcePermissions;
-import org.sonar.core.rule.DefaultRuleFinder;
-import org.sonar.core.technicaldebt.DefaultTechnicalDebtManager;
-import org.sonar.core.technicaldebt.TechnicalDebtModelRepository;
-import org.sonar.core.technicaldebt.TechnicalDebtModelSynchronizer;
-import org.sonar.core.technicaldebt.TechnicalDebtXMLImporter;
-import org.sonar.core.test.TestPlanPerspectiveLoader;
-import org.sonar.core.test.TestablePerspectiveLoader;
-import org.sonar.core.timemachine.Periods;
-import org.sonar.core.user.DefaultUserFinder;
-import org.sonar.core.user.HibernateUserFinder;
-import org.sonar.jpa.dao.MeasuresDao;
-import org.sonar.jpa.dao.ProfilesDao;
-import org.sonar.jpa.dao.RulesDao;
-import org.sonar.jpa.session.DatabaseSessionFactory;
-import org.sonar.server.charts.ChartFactory;
-import org.sonar.server.component.DefaultComponentFinder;
-import org.sonar.server.component.DefaultRubyComponentService;
-import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
-import org.sonar.server.debt.DebtModelSynchronizer;
-import org.sonar.server.debt.DebtRulesXMLImporter;
-import org.sonar.server.debt.DebtService;
-import org.sonar.server.es.ESIndex;
-import org.sonar.server.issue.ActionPlanService;
-import org.sonar.server.issue.ActionService;
-import org.sonar.server.issue.AssignAction;
-import org.sonar.server.issue.CommentAction;
-import org.sonar.server.issue.DefaultIssueFinder;
-import org.sonar.server.issue.InternalRubyIssueService;
-import org.sonar.server.issue.IssueBulkChangeService;
-import org.sonar.server.issue.IssueChangelogFormatter;
-import org.sonar.server.issue.IssueChangelogService;
-import org.sonar.server.issue.IssueCommentService;
-import org.sonar.server.issue.IssueService;
-import org.sonar.server.issue.IssueStatsFinder;
-import org.sonar.server.issue.PlanAction;
-import org.sonar.server.issue.PublicRubyIssueService;
-import org.sonar.server.issue.ServerIssueStorage;
-import org.sonar.server.issue.SetSeverityAction;
-import org.sonar.server.issue.TransitionAction;
-import org.sonar.server.issue.filter.IssueFilterService;
-import org.sonar.server.issue.filter.IssueFilterWs;
-import org.sonar.server.issue.ws.IssueShowWsHandler;
-import org.sonar.server.issue.ws.IssuesWs;
-import org.sonar.server.notifications.NotificationCenter;
-import org.sonar.server.notifications.NotificationService;
-import org.sonar.server.permission.InternalPermissionService;
-import org.sonar.server.permission.InternalPermissionTemplateService;
-import org.sonar.server.permission.PermissionFinder;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.plugins.UpdateCenterClient;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
-import org.sonar.server.qualitygate.QgateProjectFinder;
-import org.sonar.server.qualitygate.QualityGates;
-import org.sonar.server.qualitygate.ws.QgateAppHandler;
-import org.sonar.server.qualitygate.ws.QualityGatesWs;
-import org.sonar.server.qualityprofile.ESActiveRule;
-import org.sonar.server.qualityprofile.ProfilesManager;
-import org.sonar.server.qualityprofile.QProfileActiveRuleOperations;
-import org.sonar.server.qualityprofile.QProfileBackup;
-import org.sonar.server.qualityprofile.QProfileLookup;
-import org.sonar.server.qualityprofile.QProfileOperations;
-import org.sonar.server.qualityprofile.QProfileProjectLookup;
-import org.sonar.server.qualityprofile.QProfileProjectOperations;
-import org.sonar.server.qualityprofile.QProfileRepositoryExporter;
-import org.sonar.server.qualityprofile.QProfileRuleLookup;
-import org.sonar.server.qualityprofile.QProfiles;
-import org.sonar.server.rule.DeprecatedRulesDefinition;
-import org.sonar.server.rule.ESRuleTags;
-import org.sonar.server.rule.RubyRuleService;
-import org.sonar.server.rule.RuleDefinitionsLoader;
-import org.sonar.server.rule.RuleOperations;
-import org.sonar.server.rule.RuleRegistration;
-import org.sonar.server.rule.RuleRegistry;
-import org.sonar.server.rule.RuleRepositories;
-import org.sonar.server.rule.RuleTagLookup;
-import org.sonar.server.rule.RuleTagOperations;
-import org.sonar.server.rule.RuleTags;
-import org.sonar.server.rule.Rules;
-import org.sonar.server.rule.ws.AddTagsWsHandler;
-import org.sonar.server.rule.ws.RemoveTagsWsHandler;
-import org.sonar.server.rule.ws.RuleSearchWsHandler;
-import org.sonar.server.rule.ws.RuleShowWsHandler;
-import org.sonar.server.rule.ws.RuleTagsWs;
-import org.sonar.server.rule.ws.RulesWs;
-import org.sonar.server.source.CodeColorizers;
-import org.sonar.server.source.DeprecatedSourceDecorator;
-import org.sonar.server.source.HtmlSourceDecorator;
-import org.sonar.server.source.SourceService;
-import org.sonar.server.source.ws.SourcesShowWsHandler;
-import org.sonar.server.source.ws.SourcesWs;
-import org.sonar.server.startup.CleanPreviewAnalysisCache;
-import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
-import org.sonar.server.startup.GenerateBootstrapIndex;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.GwtPublisher;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.LogServerId;
-import org.sonar.server.startup.RegisterDebtModel;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewDashboards;
-import org.sonar.server.startup.RegisterNewMeasureFilters;
-import org.sonar.server.startup.RegisterNewProfiles;
-import org.sonar.server.startup.RegisterPermissionTemplates;
-import org.sonar.server.startup.RegisterServletFilters;
-import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
-import org.sonar.server.text.MacroInterpreter;
-import org.sonar.server.text.RubyTextService;
-import org.sonar.server.ui.PageDecorations;
-import org.sonar.server.ui.Views;
-import org.sonar.server.user.DefaultUserService;
-import org.sonar.server.user.GroupMembershipFinder;
-import org.sonar.server.user.GroupMembershipService;
-import org.sonar.server.user.NewUserNotifier;
-import org.sonar.server.user.SecurityRealmFactory;
-import org.sonar.server.util.BooleanTypeValidation;
-import org.sonar.server.util.FloatTypeValidation;
-import org.sonar.server.util.IntegerTypeValidation;
-import org.sonar.server.util.StringListTypeValidation;
-import org.sonar.server.util.StringTypeValidation;
-import org.sonar.server.util.TextTypeValidation;
-import org.sonar.server.util.TypeValidations;
-import org.sonar.server.ws.ListingWs;
-import org.sonar.server.ws.WebServiceEngine;
-
-public class ServerComponentsStarter {
-
-  public void start(ComponentContainer pico) {
-    registerComponents(pico);
-    pico.startComponents();
-    executeStartupTaks(pico);
-  }
-
-  private void registerComponents(ComponentContainer pico) {
-    pico.addSingleton(ESIndex.class);
-    pico.addSingleton(UpdateCenterClient.class);
-    pico.addSingleton(UpdateCenterMatrixFactory.class);
-    pico.addSingleton(PluginDownloader.class);
-    pico.addSingleton(ChartFactory.class);
-    pico.addSingleton(Languages.class);
-    pico.addSingleton(Views.class);
-    pico.addSingleton(CodeColorizers.class);
-    pico.addSingleton(ResourceTypes.class);
-    pico.addSingleton(SettingsChangeNotifier.class);
-    pico.addSingleton(PageDecorations.class);
-    pico.addSingleton(PreviewCache.class);
-    pico.addSingleton(DefaultResourcePermissions.class);
-    pico.addSingleton(Periods.class);
-
-    // quality profile
-    pico.addSingleton(XMLProfileParser.class);
-    pico.addSingleton(XMLProfileSerializer.class);
-    pico.addComponent(ProfilesDao.class, false);
-    pico.addComponent(ProfilesManager.class, false);
-    pico.addSingleton(AnnotationProfileParser.class);
-    pico.addSingleton(QProfileRuleLookup.class);
-    pico.addSingleton(QProfiles.class);
-    pico.addSingleton(QProfileLookup.class);
-    pico.addSingleton(QProfileOperations.class);
-    pico.addSingleton(QProfileActiveRuleOperations.class);
-    pico.addSingleton(QProfileProjectOperations.class);
-    pico.addSingleton(QProfileProjectLookup.class);
-    pico.addSingleton(QProfileBackup.class);
-    pico.addSingleton(QProfileRepositoryExporter.class);
-    pico.addSingleton(ESActiveRule.class);
-
-    // rule
-    pico.addSingleton(AnnotationRuleParser.class);
-    pico.addSingleton(XMLRuleParser.class);
-    pico.addComponent(RulesDao.class, false);
-    pico.addSingleton(DefaultRuleFinder.class);
-    pico.addSingleton(Rules.class);
-    pico.addSingleton(RuleOperations.class);
-    pico.addSingleton(RuleRegistry.class);
-    pico.addSingleton(RubyRuleService.class);
-    pico.addSingleton(RuleRepositories.class);
-    pico.addSingleton(RulesWs.class);
-    pico.addSingleton(RuleShowWsHandler.class);
-    pico.addSingleton(RuleSearchWsHandler.class);
-    pico.addSingleton(AddTagsWsHandler.class);
-    pico.addSingleton(RemoveTagsWsHandler.class);
-
-    // rule tags
-    pico.addSingleton(ESRuleTags.class);
-    pico.addSingleton(RuleTagLookup.class);
-    pico.addSingleton(RuleTagOperations.class);
-    pico.addSingleton(RuleTags.class);
-    pico.addSingleton(RuleTagsWs.class);
-
-    // measure
-    pico.addComponent(MeasuresDao.class, false);
-    pico.addSingleton(MeasureFilterFactory.class);
-    pico.addSingleton(MeasureFilterExecutor.class);
-    pico.addSingleton(MeasureFilterEngine.class);
-    pico.addSingleton(DefaultMetricFinder.class);
-    pico.addSingleton(ServerLifecycleNotifier.class);
-
-    // quality gates
-    pico.addSingleton(QualityGateDao.class);
-    pico.addSingleton(QualityGateConditionDao.class);
-    pico.addSingleton(QualityGates.class);
-    pico.addSingleton(ProjectQgateAssociationDao.class);
-    pico.addSingleton(QgateProjectFinder.class);
-    pico.addSingleton(QgateAppHandler.class);
-    pico.addSingleton(QualityGatesWs.class);
-
-    // web services
-    pico.addSingleton(WebServiceEngine.class);
-    pico.addSingleton(ListingWs.class);
-
-    // users
-    pico.addSingleton(SecurityRealmFactory.class);
-    pico.addSingleton(HibernateUserFinder.class);
-    pico.addSingleton(NewUserNotifier.class);
-    pico.addSingleton(DefaultUserFinder.class);
-    pico.addSingleton(DefaultUserService.class);
-
-    // groups
-    pico.addSingleton(GroupMembershipService.class);
-    pico.addSingleton(GroupMembershipFinder.class);
-
-    // permissions
-    pico.addSingleton(PermissionFacade.class);
-    pico.addSingleton(InternalPermissionService.class);
-    pico.addSingleton(InternalPermissionTemplateService.class);
-    pico.addSingleton(PermissionFinder.class);
-
-    // components
-    pico.addSingleton(DefaultComponentFinder.class);
-    pico.addSingleton(DefaultRubyComponentService.class);
-    pico.addSingleton(ComponentDao.class);
-
-    // issues
-    pico.addSingleton(ServerIssueStorage.class);
-    pico.addSingleton(IssueUpdater.class);
-    pico.addSingleton(FunctionExecutor.class);
-    pico.addSingleton(IssueWorkflow.class);
-    pico.addSingleton(IssueService.class);
-    pico.addSingleton(IssueCommentService.class);
-    pico.addSingleton(DefaultIssueFinder.class);
-    pico.addSingleton(IssueStatsFinder.class);
-    pico.addSingleton(PublicRubyIssueService.class);
-    pico.addSingleton(InternalRubyIssueService.class);
-    pico.addSingleton(ActionPlanService.class);
-    pico.addSingleton(IssueChangelogService.class);
-    pico.addSingleton(IssueNotifications.class);
-    pico.addSingleton(ActionService.class);
-    pico.addSingleton(Actions.class);
-    pico.addSingleton(IssueFilterSerializer.class);
-    pico.addSingleton(IssueFilterService.class);
-    pico.addSingleton(IssueBulkChangeService.class);
-    pico.addSingleton(IssueChangelogFormatter.class);
-    pico.addSingleton(IssueFilterWs.class);
-    pico.addSingleton(IssueShowWsHandler.class);
-    pico.addSingleton(IssuesWs.class);
-
-    // issues actions
-    pico.addSingleton(AssignAction.class);
-    pico.addSingleton(PlanAction.class);
-    pico.addSingleton(SetSeverityAction.class);
-    pico.addSingleton(CommentAction.class);
-    pico.addSingleton(TransitionAction.class);
-
-    // technical debt
-    pico.addSingleton(DebtService.class);
-    pico.addSingleton(TechnicalDebtModelSynchronizer.class);
-    pico.addSingleton(DebtModelSynchronizer.class);
-    pico.addSingleton(TechnicalDebtModelRepository.class);
-    pico.addSingleton(TechnicalDebtXMLImporter.class);
-    pico.addSingleton(DebtRulesXMLImporter.class);
-    pico.addSingleton(DebtCharacteristicsXMLImporter.class);
-    pico.addSingleton(DefaultTechnicalDebtManager.class);
-
-    // source
-    pico.addSingleton(HtmlSourceDecorator.class);
-    pico.addSingleton(DeprecatedSourceDecorator.class);
-    pico.addSingleton(SourceService.class);
-    pico.addSingleton(SourcesWs.class);
-    pico.addSingleton(SourcesShowWsHandler.class);
-
-    // text
-    pico.addSingleton(MacroInterpreter.class);
-    pico.addSingleton(RubyTextService.class);
-
-    // Notifications
-    pico.addSingleton(EmailSettings.class);
-    pico.addSingleton(NotificationService.class);
-    pico.addSingleton(NotificationCenter.class);
-    pico.addSingleton(DefaultNotificationManager.class);
-
-    // graphs and perspective related classes
-    pico.addSingleton(TestablePerspectiveLoader.class);
-    pico.addSingleton(TestPlanPerspectiveLoader.class);
-    pico.addSingleton(SnapshotPerspectives.class);
-
-    // Type validation
-    pico.addSingleton(TypeValidations.class);
-    pico.addSingleton(IntegerTypeValidation.class);
-    pico.addSingleton(FloatTypeValidation.class);
-    pico.addSingleton(BooleanTypeValidation.class);
-    pico.addSingleton(TextTypeValidation.class);
-    pico.addSingleton(StringTypeValidation.class);
-    pico.addSingleton(StringListTypeValidation.class);
-
-    ServerExtensionInstaller extensionRegistrar = pico.getComponentByType(ServerExtensionInstaller.class);
-    extensionRegistrar.installExtensions(pico);
-  }
-
-  private void executeStartupTaks(ComponentContainer pico) {
-    ComponentContainer startupContainer = pico.createChild();
-    startupContainer.addSingleton(GwtPublisher.class);
-    startupContainer.addSingleton(RegisterMetrics.class);
-    startupContainer.addSingleton(DeprecatedRulesDefinition.class);
-    startupContainer.addSingleton(RuleDefinitionsLoader.class);
-    startupContainer.addSingleton(RuleRegistration.class);
-    startupContainer.addSingleton(RegisterNewProfiles.class);
-    startupContainer.addSingleton(JdbcDriverDeployer.class);
-    startupContainer.addSingleton(RegisterDebtModel.class);
-    startupContainer.addSingleton(GeneratePluginIndex.class);
-    startupContainer.addSingleton(GenerateBootstrapIndex.class);
-    startupContainer.addSingleton(RegisterNewMeasureFilters.class);
-    startupContainer.addSingleton(RegisterNewDashboards.class);
-    startupContainer.addSingleton(RegisterPermissionTemplates.class);
-    startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
-    startupContainer.addSingleton(LogServerId.class);
-    startupContainer.addSingleton(RegisterServletFilters.class);
-    startupContainer.addSingleton(CleanPreviewAnalysisCache.class);
-    startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class);
-    startupContainer.startComponents();
-
-    startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart();
-
-    // Do not put the following statements in a finally block.
-    // It would hide the possible exception raised during startup
-    // See SONAR-3107
-    startupContainer.stopComponents();
-    pico.removeChild();
-    pico.getComponentByType(DatabaseSessionFactory.class).clear();
-  }
-}
index 94312f1337736f67300853cf011b1da9661de42c..75b080a21f3de8ec9a37d7de5f52be9f71af3aa3 100644 (file)
@@ -51,7 +51,7 @@ public class RestartHandler implements RequestHandler {
     if (settings.getBoolean("sonar.dev")) {
       Logger logger = LoggerFactory.getLogger(getClass());
       logger.info("Restart server");
-      platform.restartLevel3Container();
+      platform.restart();
       logger.info("Server restarted");
       response.noContent();
 
index bd8bf72af015685f5dd0acc5c85f3a6a354595e5..98d8741014d15164b9f0c9ab0ecd51180ed84dcc 100644 (file)
@@ -70,7 +70,6 @@ import static com.google.common.collect.Lists.newArrayList;
 public final class JRubyFacade {
 
   private static final JRubyFacade SINGLETON = new JRubyFacade();
-  private JRubyI18n i18n;
 
   public static JRubyFacade getInstance() {
     return SINGLETON;
@@ -311,10 +310,7 @@ public final class JRubyFacade {
   }
 
   private JRubyI18n getJRubyI18n() {
-    if (i18n == null) {
-      i18n = get(JRubyI18n.class);
-    }
-    return i18n;
+    return get(JRubyI18n.class);
   }
 
   public String getMessage(String rubyLocale, String key, String defaultValue, Object... parameters) {
index 8038d87644e3f0bd9bc14537e64535bd9266d802..03b2b3d6428526b0f5a4e528a049044fa86d6cb7 100644 (file)
@@ -44,7 +44,7 @@ public class RestartHandlerTest {
     WsTester tester = new WsTester(ws);
     tester.newRequest("restart").execute();
 
-    verify(platform).restartLevel3Container();
+    verify(platform).restart();
   }
 
   @Test