diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-03-14 23:17:22 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-03-14 23:17:22 +0100 |
commit | c2eab2217274ce151f2a330348d649997c278d03 (patch) | |
tree | 12fc44f7f1aba23e1a280f57d7b2e4c12a16f4a4 /sonar-batch | |
parent | 3f4f0ba6cd0380e1f918aa3d85eb0e1271775905 (diff) | |
download | sonarqube-c2eab2217274ce151f2a330348d649997c278d03.tar.gz sonarqube-c2eab2217274ce151f2a330348d649997c278d03.zip |
Improve exception handling of pico container lifecycle
Diffstat (limited to 'sonar-batch')
7 files changed, 186 insertions, 202 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java index eb808e74ed6..d8491e18758 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java @@ -33,6 +33,8 @@ import org.sonar.batch.components.PastSnapshotFinderByDays; import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; import org.sonar.batch.components.PastSnapshotFinderByVersion; +import org.sonar.batch.scan.ScanTask; +import org.sonar.batch.tasks.ListTask; import org.sonar.core.config.Logback; import org.sonar.core.i18n.I18nManager; import org.sonar.core.i18n.RuleI18nManager; @@ -60,6 +62,12 @@ public class BootstrapContainer extends ComponentContainer { super(); } + public static BootstrapContainer create(List objects) { + BootstrapContainer container = new BootstrapContainer(); + container.add(objects); + return container; + } + @Override protected void doBeforeStart() { addBootstrapComponents(); @@ -69,36 +77,36 @@ public class BootstrapContainer extends ComponentContainer { private void addBootstrapComponents() { add( - new PropertiesConfiguration(), - BootstrapSettings.class, - PluginDownloader.class, - BatchPluginRepository.class, - BatchSettings.class, - ServerClient.class, - ExtensionInstaller.class, - Logback.class, - ServerMetadata.class, - org.sonar.batch.ServerMetadata.class, - TempDirectories.class, - HttpDownloader.class, - UriReader.class, - new FileCacheProvider() + new PropertiesConfiguration(), + BootstrapSettings.class, + PluginDownloader.class, + BatchPluginRepository.class, + BatchSettings.class, + ServerClient.class, + ExtensionInstaller.class, + Logback.class, + ServerMetadata.class, + org.sonar.batch.ServerMetadata.class, + TempDirectories.class, + HttpDownloader.class, + UriReader.class, + new FileCacheProvider() ); } private void addDatabaseComponents() { add( - DryRunDatabase.class, - JdbcDriverHolder.class, - BatchDatabase.class, - MyBatis.class, - DatabaseVersion.class, - //TODO check that it still works (see @Freddy) - DatabaseCompatibility.class, - DefaultDatabaseConnector.class, - JpaDatabaseSession.class, - BatchDatabaseSessionFactory.class, - DaoUtils.getDaoClasses() + DryRunDatabase.class, + JdbcDriverHolder.class, + BatchDatabase.class, + MyBatis.class, + DatabaseVersion.class, + //TODO check that it still works (see @Freddy) + DatabaseCompatibility.class, + DefaultDatabaseConnector.class, + JpaDatabaseSession.class, + BatchDatabaseSessionFactory.class, + DaoUtils.getDaoClasses() ); } @@ -107,44 +115,43 @@ public class BootstrapContainer extends ComponentContainer { */ private void addCoreComponents() { add( - EmailSettings.class, - I18nManager.class, - RuleI18nManager.class, - MeasuresDao.class, - RulesDao.class, - ProfilesDao.class, - CacheRuleFinder.class, - CacheMetricFinder.class, - DefaultUserFinder.class, - SemaphoreUpdater.class, - SemaphoresImpl.class, - PastSnapshotFinderByDate.class, - PastSnapshotFinderByDays.class, - PastSnapshotFinderByPreviousAnalysis.class, - PastSnapshotFinderByVersion.class, - PastSnapshotFinderByPreviousVersion.class, - PastMeasuresLoader.class, - PastSnapshotFinder.class, - DefaultModelFinder.class + EmailSettings.class, + I18nManager.class, + RuleI18nManager.class, + MeasuresDao.class, + RulesDao.class, + ProfilesDao.class, + CacheRuleFinder.class, + CacheMetricFinder.class, + DefaultUserFinder.class, + SemaphoreUpdater.class, + SemaphoresImpl.class, + PastSnapshotFinderByDate.class, + PastSnapshotFinderByDays.class, + PastSnapshotFinderByPreviousAnalysis.class, + PastSnapshotFinderByVersion.class, + PastSnapshotFinderByPreviousVersion.class, + PastMeasuresLoader.class, + PastSnapshotFinder.class, + DefaultModelFinder.class ); } @Override protected void doAfterStart() { installPlugins(); + executeTask(); } private void installPlugins() { - for (Map.Entry<PluginMetadata, Plugin> entry : get(BatchPluginRepository.class).getPluginsByMetadata().entrySet()) { + for (Map.Entry<PluginMetadata, Plugin> entry : getComponentByType(BatchPluginRepository.class).getPluginsByMetadata().entrySet()) { PluginMetadata metadata = entry.getKey(); Plugin plugin = entry.getValue(); addExtension(metadata, plugin); } } - public static BootstrapContainer create(List objects) { - BootstrapContainer container = new BootstrapContainer(); - container.add(objects); - return container; + void executeTask() { + new TaskContainer(this).execute(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java index bc50ede3ea2..d1772e1497c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java @@ -27,6 +27,8 @@ import org.sonar.api.task.Task; import org.sonar.api.task.TaskDefinition; import org.sonar.api.task.TaskExtension; import org.sonar.api.utils.SonarException; +import org.sonar.batch.scan.ScanTask; +import org.sonar.batch.tasks.ListTask; import org.sonar.batch.tasks.Tasks; public class TaskContainer extends ComponentContainer { @@ -37,30 +39,20 @@ public class TaskContainer extends ComponentContainer { @Override protected void doBeforeStart() { + installCoreTasks(); installTaskExtensions(); installComponentsUsingTaskExtensions(); } - public void execute() { - startComponents(); - - // default value is declared in CorePlugin - String taskKey = get(Settings.class).getString(CoreProperties.TASK); - - TaskDefinition def = get(Tasks.class).definition(taskKey); - if (def == null) { - throw new SonarException("Task " + taskKey + " does not exist."); - } - Task task = get(def.taskClass()); - if (task != null) { - task.execute(); - } else { - throw new IllegalStateException("Task " + taskKey + " is badly defined."); - } + private void installCoreTasks() { + add( + ScanTask.DEFINITION, ScanTask.class, + ListTask.DEFINITION, ListTask.class + ); } private void installTaskExtensions() { - get(ExtensionInstaller.class).install(this, new ExtensionInstaller.ComponentFilter() { + getComponentByType(ExtensionInstaller.class).install(this, new ExtensionInstaller.ComponentFilter() { public boolean accept(Object extension) { return ExtensionUtils.isType(extension, TaskExtension.class); } @@ -70,4 +62,21 @@ public class TaskContainer extends ComponentContainer { private void installComponentsUsingTaskExtensions() { add(ResourceTypes.class, MetricProvider.class, Tasks.class); } + + @Override + public void doAfterStart() { + // default value is declared in CorePlugin + String taskKey = getComponentByType(Settings.class).getString(CoreProperties.TASK); + + TaskDefinition def = getComponentByType(Tasks.class).definition(taskKey); + if (def == null) { + throw new SonarException("Task " + taskKey + " does not exist"); + } + Task task = getComponentByType(def.taskClass()); + if (task != null) { + task.execute(); + } else { + throw new IllegalStateException("Task " + taskKey + " is badly defined"); + } + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index fd2ed69ac6c..d7459b0e7a7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -21,14 +21,9 @@ package org.sonar.batch.bootstrapper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.batch.bootstrap.BootstrapContainer; import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.TaskContainer; -import org.sonar.batch.scan.ScanTask; -import org.sonar.batch.tasks.ListTask; -import org.sonar.core.PicoUtils; import java.util.Collections; import java.util.List; @@ -81,37 +76,14 @@ public final class Batch { } private void startBatch() { - BootstrapContainer bootstrapContainer = null; - try { - List all = Lists.newArrayList(components); - all.add(new BootstrapProperties(bootstrapProperties)); - if (projectReactor != null) { - all.add(projectReactor); - } - - bootstrapContainer = BootstrapContainer.create(all); - bootstrapContainer.startComponents(); - - TaskContainer taskContainer = new TaskContainer(bootstrapContainer); - taskContainer.add( - ScanTask.DEFINITION, ScanTask.class, - ListTask.DEFINITION, ListTask.class - ); - - taskContainer.execute(); - - } catch (RuntimeException e) { - PicoUtils.propagateStartupException(e); - } finally { - try { - if (bootstrapContainer != null) { - bootstrapContainer.stopComponents(); - } - } catch (Exception e) { - // never throw exceptions in a finally block - LoggerFactory.getLogger(Batch.class).error("Error while stopping batch", e); - } + List all = Lists.newArrayList(components); + all.add(new BootstrapProperties(bootstrapProperties)); + if (projectReactor != null) { + all.add(projectReactor); } + + BootstrapContainer bootstrapContainer = BootstrapContainer.create(all); + bootstrapContainer.execute(); } public static Builder builder() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index b85b7e75bb4..0e001d1c3b7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -71,54 +71,54 @@ public class ModuleScanContainer extends ComponentContainer { } private void addCoreComponents() { - ProjectDefinition moduleDefinition = get(ProjectTree.class).getProjectDefinition(module); + ProjectDefinition moduleDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(module); add( - moduleDefinition, - module.getConfiguration(), - module, - ModuleSettings.class); + moduleDefinition, + module.getConfiguration(), + module, + ModuleSettings.class); // hack to initialize commons-configuration before ExtensionProviders - get(ModuleSettings.class); + getComponentByType(ModuleSettings.class); add( - EventBus.class, - Phases.class, - PhasesTimeProfiler.class, - UnsupportedProperties.class, - Phases.getPhaseClasses(), - moduleDefinition.getContainerExtensions(), - - // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql) - Languages.class, - - // file system - PathResolver.class, - FileExclusions.class, - LanguageFilters.class, - ExclusionFilters.class, - DefaultProjectClasspath.class, - new ModuleFileSystemProvider(), - DeprecatedFileSystemAdapter.class, - FileSystemLogger.class, - - // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) - get(ResourcePersister.class).getSnapshot(module), - - TimeMachineConfiguration.class, - org.sonar.api.database.daos.MeasuresDao.class, - DefaultSensorContext.class, - BatchExtensionDictionnary.class, - DefaultTimeMachine.class, - ViolationFilters.class, - ResourceFilters.class, - DefaultProfileLoader.class, - DryRunExporter.class, - new ProfileProvider()); + EventBus.class, + Phases.class, + PhasesTimeProfiler.class, + UnsupportedProperties.class, + Phases.getPhaseClasses(), + moduleDefinition.getContainerExtensions(), + + // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql) + Languages.class, + + // file system + PathResolver.class, + FileExclusions.class, + LanguageFilters.class, + ExclusionFilters.class, + DefaultProjectClasspath.class, + new ModuleFileSystemProvider(), + DeprecatedFileSystemAdapter.class, + FileSystemLogger.class, + + // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) + getComponentByType(ResourcePersister.class).getSnapshot(module), + + TimeMachineConfiguration.class, + org.sonar.api.database.daos.MeasuresDao.class, + DefaultSensorContext.class, + BatchExtensionDictionnary.class, + DefaultTimeMachine.class, + ViolationFilters.class, + ResourceFilters.class, + DefaultProfileLoader.class, + DryRunExporter.class, + new ProfileProvider()); } private void addExtensions() { - ExtensionInstaller installer = get(ExtensionInstaller.class); + ExtensionInstaller installer = getComponentByType(ExtensionInstaller.class); installer.install(this, new ExtensionInstaller.ComponentFilter() { public boolean accept(Object extension) { if (ExtensionUtils.isType(extension, BatchExtension.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT)) { @@ -134,14 +134,13 @@ public class ModuleScanContainer extends ComponentContainer { @Override protected void doAfterStart() { - DefaultIndex index = get(DefaultIndex.class); + DefaultIndex index = getComponentByType(DefaultIndex.class); index.setCurrentProject(module, - get(ResourceFilters.class), - get(ViolationFilters.class), - get(RulesProfile.class)); + getComponentByType(ResourceFilters.class), + getComponentByType(ViolationFilters.class), + getComponentByType(RulesProfile.class)); - get(Phases.class).execute(module); + getComponentByType(Phases.class).execute(module); } - } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 74eaedaab4a..f57bbb2e085 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -63,52 +63,52 @@ public class ProjectScanContainer extends ComponentContainer { private void addBatchComponents() { add( - DefaultResourceCreationLock.class, - DefaultPersistenceManager.class, - DependencyPersister.class, - EventPersister.class, - LinkPersister.class, - MeasurePersister.class, - MemoryOptimizer.class, - DefaultResourcePermissions.class, - DefaultResourcePersister.class, - SourcePersister.class, - DefaultNotificationManager.class, - MetricProvider.class, - ProjectExclusions.class, - ProjectReactorReady.class, - ProjectTree.class, - ProjectConfigurator.class, - DefaultIndex.class, - DefaultFileLinesContextFactory.class, - ProjectLock.class, - LastSnapshots.class, - ScanGraph.create(), - TestPlanBuilder.class, - TestableBuilder.class, - ScanPerspectives.class, - ScanGraphStore.class + DefaultResourceCreationLock.class, + DefaultPersistenceManager.class, + DependencyPersister.class, + EventPersister.class, + LinkPersister.class, + MeasurePersister.class, + MemoryOptimizer.class, + DefaultResourcePermissions.class, + DefaultResourcePersister.class, + SourcePersister.class, + DefaultNotificationManager.class, + MetricProvider.class, + ProjectExclusions.class, + ProjectReactorReady.class, + ProjectTree.class, + ProjectConfigurator.class, + DefaultIndex.class, + DefaultFileLinesContextFactory.class, + ProjectLock.class, + LastSnapshots.class, + ScanGraph.create(), + TestPlanBuilder.class, + TestableBuilder.class, + ScanPerspectives.class, + ScanGraphStore.class ); } private void fixMavenExecutor() { - if (get(MavenPluginExecutor.class) == null) { + if (getComponentByType(MavenPluginExecutor.class) == null) { add(FakeMavenPluginExecutor.class); } } private void addBatchExtensions() { - get(ExtensionInstaller.class).install(this, new ExtensionInstaller.ComponentFilter() { + getComponentByType(ExtensionInstaller.class).install(this, new ExtensionInstaller.ComponentFilter() { public boolean accept(Object extension) { return ExtensionUtils.isType(extension, BatchExtension.class) - && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_BATCH); + && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_BATCH); } }); } @Override protected void doAfterStart() { - ProjectTree tree = get(ProjectTree.class); + ProjectTree tree = getComponentByType(ProjectTree.class); scanRecursively(tree.getRootProject()); } @@ -120,13 +120,7 @@ public class ProjectScanContainer extends ComponentContainer { } private void scan(Project module) { - ModuleScanContainer moduleContainer = new ModuleScanContainer(this, module); - try { - moduleContainer.startComponents(); - } finally { - moduleContainer.stopComponents(); - removeChild(); - } + new ModuleScanContainer(this, module).execute(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java index f573be1d0fa..db3a4d21bfe 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java @@ -33,7 +33,9 @@ import java.util.Collections; import java.util.List; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; public class BootstrapContainerTest { @@ -42,8 +44,8 @@ public class BootstrapContainerTest { BootstrapContainer container = BootstrapContainer.create(Collections.emptyList()); container.doBeforeStart(); - assertThat(container.get(Logback.class)).isNotNull(); - assertThat(container.get(TempDirectories.class)).isNotNull(); + assertThat(container.getComponentByType(Logback.class)).isNotNull(); + assertThat(container.getComponentByType(TempDirectories.class)).isNotNull(); } @Test @@ -51,8 +53,8 @@ public class BootstrapContainerTest { BootstrapContainer container = BootstrapContainer.create(Lists.newArrayList(Foo.class, new Bar())); container.doBeforeStart(); - assertThat(container.get(Foo.class)).isNotNull(); - assertThat(container.get(Bar.class)).isNotNull(); + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNotNull(); } @Test @@ -64,7 +66,8 @@ public class BootstrapContainerTest { metadata, plugin )); - BootstrapContainer container = BootstrapContainer.create(Lists.newArrayList(pluginRepository)); + BootstrapContainer container = spy(BootstrapContainer.create(Lists.newArrayList(pluginRepository))); + doNothing().when(container).executeTask(); container.doAfterStart(); assertThat(container.getComponentsByType(Plugin.class)).containsOnly(plugin); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java index 23e2a311bf4..c7fbaa32855 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java @@ -47,11 +47,11 @@ public class ExtensionInstallerTest { Map<PluginMetadata, Plugin> newPlugin(final Object... extensions) { Map<PluginMetadata, Plugin> result = Maps.newHashMap(); result.put(metadata, - new SonarPlugin() { - public List<?> getExtensions() { - return Arrays.asList(extensions); - } + new SonarPlugin() { + public List<?> getExtensions() { + return Arrays.asList(extensions); } + } ); return result; } @@ -64,8 +64,8 @@ public class ExtensionInstallerTest { ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings()); installer.install(container, new FooMatcher()); - assertThat(container.get(Foo.class)).isNotNull(); - assertThat(container.get(Bar.class)).isNull(); + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNull(); } @Test @@ -77,8 +77,8 @@ public class ExtensionInstallerTest { installer.install(container, new FooMatcher()); - assertThat(container.get(Foo.class)).isNotNull(); - assertThat(container.get(Bar.class)).isNull(); + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNull(); } @Test @@ -90,8 +90,8 @@ public class ExtensionInstallerTest { installer.install(container, new TrueMatcher()); - assertThat(container.get(Foo.class)).isNotNull(); - assertThat(container.get(Bar.class)).isNotNull(); + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNotNull(); } @Test @@ -104,10 +104,10 @@ public class ExtensionInstallerTest { installer.install(container, new TrueMatcher()); - assertThat(container.get(MavenExtension.class)).isNull(); - assertThat(container.get(AntExtension.class)).isNotNull(); - assertThat(container.get(Foo.class)).isNotNull(); - assertThat(container.get(Bar.class)).isNotNull(); + assertThat(container.getComponentByType(MavenExtension.class)).isNull(); + assertThat(container.getComponentByType(AntExtension.class)).isNotNull(); + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNotNull(); } private static class FooMatcher implements ExtensionInstaller.ComponentFilter { |