diff options
Diffstat (limited to 'sonar-scanner-engine/src/main/java/org/sonar')
64 files changed, 851 insertions, 438 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/bootstrapper/Batch.java index c1a672ce590..5d616b9e035 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; import org.sonar.api.utils.MessageException; -import org.sonar.scanner.bootstrap.GlobalContainer; +import org.sonar.scanner.bootstrap.SpringGlobalContainer; /** * Entry point for SonarQube Scanner API 2.1+. @@ -69,7 +69,7 @@ public final class Batch { public synchronized Batch doExecute(Map<String, String> scannerProperties, List<Object> components) { configureLogging(); try { - GlobalContainer.create(scannerProperties, components).execute(); + SpringGlobalContainer.create(scannerProperties, components).execute(); } catch (RuntimeException e) { throw handleException(e); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectInfo.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectInfo.java index cf130f161f2..8c7a8309fa5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectInfo.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectInfo.java @@ -24,8 +24,8 @@ import java.util.Date; import java.util.Optional; import java.util.function.Predicate; import org.apache.commons.lang.StringUtils; -import org.picocontainer.Startable; import org.sonar.api.CoreProperties; +import org.sonar.api.Startable; import org.sonar.api.config.Configuration; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.MessageException; @@ -41,7 +41,7 @@ import static org.sonar.api.CoreProperties.PROJECT_VERSION_PROPERTY; */ public class ProjectInfo implements Startable { private final Clock clock; - private Configuration settings; + private final Configuration settings; private Date analysisDate; private String projectVersion; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java index da406611440..753a6f3b711 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java @@ -22,58 +22,25 @@ package org.sonar.scanner.analysis; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import org.picocontainer.ComponentLifecycle; -import org.picocontainer.PicoContainer; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.impl.utils.DefaultTempFolder; import org.sonar.api.utils.TempFolder; +import org.springframework.context.annotation.Bean; -public class AnalysisTempFolderProvider extends ProviderAdapter implements ComponentLifecycle<TempFolder> { +public class AnalysisTempFolderProvider { static final String TMP_NAME = ".sonartmp"; - private DefaultTempFolder projectTempFolder; - private boolean started = false; + @Bean("TempFolder") public TempFolder provide(DefaultInputProject project) { - if (projectTempFolder == null) { - Path workingDir = project.getWorkDir(); - Path tempDir = workingDir.normalize().resolve(TMP_NAME); - try { - Files.deleteIfExists(tempDir); - Files.createDirectories(tempDir); - } catch (IOException e) { - throw new IllegalStateException("Unable to create root temp directory " + tempDir, e); - } - - projectTempFolder = new DefaultTempFolder(tempDir.toFile(), true); - } - return projectTempFolder; - } - - @Override - public void start(PicoContainer container) { - started = true; - } - - @Override - public void stop(PicoContainer container) { - if (projectTempFolder != null) { - projectTempFolder.stop(); + Path workingDir = project.getWorkDir(); + Path tempDir = workingDir.normalize().resolve(TMP_NAME); + try { + Files.deleteIfExists(tempDir); + Files.createDirectories(tempDir); + } catch (IOException e) { + throw new IllegalStateException("Unable to create root temp directory " + tempDir, e); } - } - - @Override - public void dispose(PicoContainer container) { - // nothing to do - } - - @Override - public boolean componentHasLifecycle() { - return true; - } - @Override - public boolean isStarted() { - return started; + return new DefaultTempFolder(tempDir.toFile(), true); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java index 46b79847d06..6a8c5071466 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java @@ -35,13 +35,13 @@ import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.Phase; import org.sonar.api.utils.AnnotationUtils; import org.sonar.api.utils.dag.DirectAcyclicGraph; -import org.sonar.core.platform.ComponentContainer; +import org.sonar.core.platform.ExtensionContainer; public abstract class AbstractExtensionDictionary { - private final ComponentContainer componentContainer; + private final ExtensionContainer componentContainer; - public AbstractExtensionDictionary(ComponentContainer componentContainer) { + protected AbstractExtensionDictionary(ExtensionContainer componentContainer) { this.componentContainer = componentContainer; } @@ -78,9 +78,9 @@ public abstract class AbstractExtensionDictionary { return extensions; } - private static <T> void completeScannerExtensions(ComponentContainer container, List<T> extensions, Class<T> type) { + private static <T> void completeScannerExtensions(ExtensionContainer container, List<T> extensions, Class<T> type) { extensions.addAll(container.getComponentsByType(type)); - ComponentContainer parentContainer = container.getParent(); + ExtensionContainer parentContainer = container.getParent(); if (parentContainer != null) { completeScannerExtensions(parentContainer, extensions, type); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java new file mode 100644 index 00000000000..0743b81f1f6 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java @@ -0,0 +1,62 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.bootstrap; + +import java.lang.reflect.Constructor; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.lang.Nullable; + +/** + * Taken from Spring's GenericApplicationContext.ClassDerivedBeanDefinition. + */ +public class ClassDerivedBeanDefinition extends RootBeanDefinition { + public ClassDerivedBeanDefinition(Class<?> beanClass) { + super(beanClass); + } + + public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) { + super(original); + } + + /** + * This method gets called from AbstractAutowireCapableBeanFactory#createBeanInstance when a bean is instantiated. + * It first tries to look at annotations or any other methods provided by bean post processors. If a constructor can't be determined, it will fallback to this method. + */ + @Override + @Nullable + public Constructor<?>[] getPreferredConstructors() { + Class<?> clazz = getBeanClass(); + Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz); + if (primaryCtor != null) { + return new Constructor<?>[] {primaryCtor}; + } + Constructor<?>[] publicCtors = clazz.getConstructors(); + if (publicCtors.length > 0) { + return publicCtors; + } + return null; + } + + @Override + public RootBeanDefinition cloneBeanDefinition() { + return new ClassDerivedBeanDefinition(this); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java index ee037f90c46..a749bf13b84 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java @@ -24,7 +24,7 @@ import org.sonar.api.Plugin; import org.sonar.api.SonarRuntime; import org.sonar.api.config.Configuration; import org.sonar.api.internal.PluginContextImpl; -import org.sonar.core.platform.ComponentContainer; +import org.sonar.core.platform.ExtensionContainer; import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; @@ -40,8 +40,7 @@ public class ExtensionInstaller { this.bootConfiguration = bootConfiguration; } - public ExtensionInstaller install(ComponentContainer container, ExtensionMatcher matcher) { - + public ExtensionInstaller install(ExtensionContainer container, ExtensionMatcher matcher) { // core components for (Object o : BatchComponents.all()) { doInstall(container, matcher, null, o); @@ -64,7 +63,7 @@ public class ExtensionInstaller { return this; } - private static void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginInfo pluginInfo, Object extension) { + private static void doInstall(ExtensionContainer container, ExtensionMatcher matcher, @Nullable PluginInfo pluginInfo, Object extension) { if (matcher.accept(extension)) { container.addExtension(pluginInfo, extension); } else { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java index f0fb379f5b6..19070c28360 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java @@ -21,15 +21,13 @@ package org.sonar.scanner.bootstrap; import java.util.Map; import javax.annotation.concurrent.Immutable; -import org.sonar.api.config.internal.Encryption; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.internal.Encryption; import org.sonar.scanner.config.DefaultConfiguration; @Immutable public class GlobalConfiguration extends DefaultConfiguration { - public GlobalConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> settings) { super(propertyDefinitions, encryption, settings); } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfigurationProvider.java index cad8c08c367..af1323367ee 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfigurationProvider.java @@ -21,22 +21,15 @@ package org.sonar.scanner.bootstrap; import java.util.LinkedHashMap; import java.util.Map; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.config.PropertyDefinitions; +import org.springframework.context.annotation.Bean; -public class GlobalConfigurationProvider extends ProviderAdapter { - - private GlobalConfiguration globalConfig; - - public GlobalConfiguration provide(GlobalServerSettings globalServerSettings, ScannerProperties scannerProps, - PropertyDefinitions propertyDefinitions) { - if (globalConfig == null) { - Map<String, String> mergedSettings = new LinkedHashMap<>(); - mergedSettings.putAll(globalServerSettings.properties()); - mergedSettings.putAll(scannerProps.properties()); - - globalConfig = new GlobalConfiguration(propertyDefinitions, scannerProps.getEncryption(), mergedSettings); - } - return globalConfig; +public class GlobalConfigurationProvider { + @Bean("GlobalConfiguration") + public GlobalConfiguration provide(GlobalServerSettings globalServerSettings, ScannerProperties scannerProps, PropertyDefinitions propertyDefinitions) { + Map<String, String> mergedSettings = new LinkedHashMap<>(); + mergedSettings.putAll(globalServerSettings.properties()); + mergedSettings.putAll(scannerProps.properties()); + return new GlobalConfiguration(propertyDefinitions, scannerProps.getEncryption(), mergedSettings); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalServerSettingsProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalServerSettingsProvider.java index 9a373193f7f..8f8bca6dea6 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalServerSettingsProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalServerSettingsProvider.java @@ -21,24 +21,19 @@ package org.sonar.scanner.bootstrap; import java.util.Map; import java.util.Optional; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.repository.settings.GlobalSettingsLoader; +import org.springframework.context.annotation.Bean; -public class GlobalServerSettingsProvider extends ProviderAdapter { - +public class GlobalServerSettingsProvider { private static final Logger LOG = Loggers.get(GlobalServerSettingsProvider.class); - private GlobalServerSettings singleton; - + @Bean("GlobalServerSettings") public GlobalServerSettings provide(GlobalSettingsLoader loader) { - if (singleton == null) { - Map<String, String> serverSideSettings = loader.loadGlobalSettings(); - singleton = new GlobalServerSettings(serverSideSettings); - Optional.ofNullable(serverSideSettings.get(CoreProperties.SERVER_ID)).ifPresent(v -> LOG.info("Server id: {}", v)); - } - return singleton; + Map<String, String> serverSideSettings = loader.loadGlobalSettings(); + Optional.ofNullable(serverSideSettings.get(CoreProperties.SERVER_ID)).ifPresent(v -> LOG.info("Server id: {}", v)); + return new GlobalServerSettings(serverSideSettings); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java index 0fdf444b7c9..4cc825c1930 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java @@ -27,23 +27,21 @@ import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.TimeUnit; import org.apache.commons.lang.StringUtils; -import org.picocontainer.ComponentLifecycle; -import org.picocontainer.PicoContainer; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; +import org.sonar.api.Startable; import org.sonar.api.impl.utils.DefaultTempFolder; import org.sonar.api.utils.System2; import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.springframework.context.annotation.Bean; import static org.sonar.core.util.FileUtils.deleteQuietly; -public class GlobalTempFolderProvider extends ProviderAdapter implements ComponentLifecycle<TempFolder> { +public class GlobalTempFolderProvider implements Startable { private static final Logger LOG = Loggers.get(GlobalTempFolderProvider.class); private static final long CLEAN_MAX_AGE = TimeUnit.DAYS.toMillis(21); static final String TMP_NAME_PREFIX = ".sonartmp_"; - private boolean started = false; private System2 system; private DefaultTempFolder tempFolder; @@ -56,6 +54,7 @@ public class GlobalTempFolderProvider extends ProviderAdapter implements Compone this.system = system; } + @Bean("TempFolder") public TempFolder provide(ScannerProperties scannerProps) { if (tempFolder == null) { @@ -150,29 +149,14 @@ public class GlobalTempFolderProvider extends ProviderAdapter implements Compone } @Override - public void start(PicoContainer container) { - started = true; + public void start() { + // nothing to do } @Override - public void stop(PicoContainer container) { + public void stop() { if (tempFolder != null) { tempFolder.stop(); } } - - @Override - public void dispose(PicoContainer container) { - // nothing to do - } - - @Override - public boolean componentHasLifecycle() { - return true; - } - - @Override - public boolean isStarted() { - return started; - } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java new file mode 100644 index 00000000000..61fcb419d60 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java @@ -0,0 +1,35 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.bootstrap; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; + +public class LazyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + for (String beanName : beanFactory.getBeanDefinitionNames()) { + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + beanDefinition.setLazyInit(true); + } + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginFiles.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginFiles.java index 371df48fab5..8e31b44d4ad 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginFiles.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginFiles.java @@ -181,7 +181,7 @@ public class PluginFiles { LOGGER.debug("Unpacking plugin {}", pluginKey); File jar = newTempFile(); try (InputStream input = new GZIPInputStream(new BufferedInputStream(FileUtils.openInputStream(compressedFile))); - JarOutputStream output = new JarOutputStream(new BufferedOutputStream(FileUtils.openOutputStream(jar)))) { + JarOutputStream output = new JarOutputStream(new BufferedOutputStream(FileUtils.openOutputStream(jar)))) { Pack200.newUnpacker().unpack(input, output); } catch (IOException e) { throw new IllegalStateException(format("Fail to download plugin [%s]. Pack200 error.", pluginKey), e); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionary.java index 171376a5fcb..9f94b6fe43b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionary.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionary.java @@ -23,7 +23,7 @@ import java.util.Collection; import java.util.stream.Collectors; import org.sonar.api.batch.postjob.PostJob; import org.sonar.api.batch.postjob.PostJobContext; -import org.sonar.core.platform.ComponentContainer; +import org.sonar.core.platform.ExtensionContainer; import org.sonar.scanner.postjob.PostJobOptimizer; import org.sonar.scanner.postjob.PostJobWrapper; @@ -32,8 +32,8 @@ public class PostJobExtensionDictionary extends AbstractExtensionDictionary { private final PostJobContext postJobContext; private final PostJobOptimizer postJobOptimizer; - public PostJobExtensionDictionary(ComponentContainer componentContainer, PostJobOptimizer postJobOptimizer, PostJobContext postJobContext) { - super(componentContainer); + public PostJobExtensionDictionary(ExtensionContainer container, PostJobOptimizer postJobOptimizer, PostJobContext postJobContext) { + super(container); this.postJobOptimizer = postJobOptimizer; this.postJobContext = postJobContext; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java new file mode 100644 index 00000000000..6d5a73b2369 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java @@ -0,0 +1,123 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.bootstrap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; + +public class PriorityBeanFactory extends DefaultListableBeanFactory { + /** + * Determines highest priority of the bean candidates. + * Does not take into account the @Primary annotations. + * This gets called from {@link DefaultListableBeanFactory#determineAutowireCandidate} when the bean factory is finding the beans to autowire. That method + * checks for @Primary before calling this method. + * + * The strategy is to look at the @Priority annotations. If there are ties, we give priority to components that were added to child containers over their parents. + * If there are still ties, null is returned, which will ultimately cause Spring to throw a NoUniqueBeanDefinitionException. + */ + @Override + @Nullable + protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) { + List<Bean> candidateBeans = candidates.entrySet().stream() + .filter(e -> e.getValue() != null) + .map(e -> new Bean(e.getKey(), e.getValue())) + .collect(Collectors.toUnmodifiableList()); + + List<Bean> beansAfterPriority = highestPriority(candidateBeans, b -> getPriority(b.getInstance())); + if (beansAfterPriority.isEmpty()) { + return null; + } else if (beansAfterPriority.size() == 1) { + return beansAfterPriority.get(0).getName(); + } + + List<Bean> beansAfterHierarchy = highestPriority(beansAfterPriority, b -> getHierarchyPriority(b.getName())); + if (beansAfterHierarchy.size() == 1) { + return beansAfterHierarchy.get(0).getName(); + } + + return null; + } + + private static List<Bean> highestPriority(List<Bean> candidates, PriorityFunction function) { + List<Bean> highestPriorityBeans = new ArrayList<>(); + Integer highestPriority = null; + + for (Bean candidate : candidates) { + Integer candidatePriority = function.classify(candidate); + if (candidatePriority == null) { + candidatePriority = Integer.MAX_VALUE; + } + if (highestPriority == null) { + highestPriority = candidatePriority; + highestPriorityBeans.add(candidate); + } else if (candidatePriority < highestPriority) { + highestPriorityBeans.clear(); + highestPriority = candidatePriority; + highestPriorityBeans.add(candidate); + } else if (candidatePriority.equals(highestPriority)) { + highestPriorityBeans.add(candidate); + } + } + return highestPriorityBeans; + } + + @CheckForNull + private Integer getHierarchyPriority(String beanName) { + DefaultListableBeanFactory factory = this; + int i = 1; + while (factory != null) { + if (factory.containsBeanDefinition(beanName)) { + return i; + } + factory = (DefaultListableBeanFactory) factory.getParentBeanFactory(); + i++; + } + return null; + } + + private static class Bean { + private final String name; + private final Object instance; + + public Bean(String name, Object instance) { + this.name = name; + this.instance = instance; + } + + public String getName() { + return name; + } + + public Object getInstance() { + return instance; + } + } + + @FunctionalInterface + private interface PriorityFunction { + @Nullable + Integer classify(Bean candidate); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java index c62fc09908a..fcf68cc3a04 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java @@ -24,8 +24,8 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import javax.annotation.CheckForNull; -import org.picocontainer.Startable; import org.sonar.api.Plugin; +import org.sonar.api.Startable; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.platform.ExplodedPlugin; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java index db3abc561b1..678b26f17fd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java @@ -19,49 +19,43 @@ */ package org.sonar.scanner.bootstrap; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; import org.sonar.api.utils.System2; import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonarqube.ws.client.HttpConnector; import org.sonarqube.ws.client.WsClientFactories; +import org.springframework.context.annotation.Bean; import static java.lang.Integer.parseInt; import static java.lang.String.valueOf; import static org.apache.commons.lang.StringUtils.defaultIfBlank; -public class ScannerWsClientProvider extends ProviderAdapter { - +public class ScannerWsClientProvider { static final int CONNECT_TIMEOUT_MS = 5_000; static final String READ_TIMEOUT_SEC_PROPERTY = "sonar.ws.timeout"; static final int DEFAULT_READ_TIMEOUT_SEC = 60; - private DefaultScannerWsClient wsClient; - - public synchronized DefaultScannerWsClient provide(final ScannerProperties scannerProps, - final EnvironmentInformation env, GlobalAnalysisMode globalMode, System2 system) { - if (wsClient == null) { - String url = defaultIfBlank(scannerProps.property("sonar.host.url"), "http://localhost:9000"); - HttpConnector.Builder connectorBuilder = HttpConnector.newBuilder(); - - String timeoutSec = defaultIfBlank(scannerProps.property(READ_TIMEOUT_SEC_PROPERTY), valueOf(DEFAULT_READ_TIMEOUT_SEC)); - String token = defaultIfBlank(system.envVariable("SONAR_TOKEN"), null); - String login = defaultIfBlank(scannerProps.property(CoreProperties.LOGIN), token); - connectorBuilder - .readTimeoutMilliseconds(parseInt(timeoutSec) * 1_000) - .connectTimeoutMilliseconds(CONNECT_TIMEOUT_MS) - .userAgent(env.toString()) - .url(url) - .credentials(login, scannerProps.property(CoreProperties.PASSWORD)); - - // OkHttp detect 'http.proxyHost' java property, but credentials should be filled - final String proxyUser = System.getProperty("http.proxyUser", ""); - if (!proxyUser.isEmpty()) { - connectorBuilder.proxyCredentials(proxyUser, System.getProperty("http.proxyPassword")); - } - - wsClient = new DefaultScannerWsClient(WsClientFactories.getDefault().newClient(connectorBuilder.build()), login != null, globalMode); + @Bean("DefaultScannerWsClient") + public DefaultScannerWsClient provide(ScannerProperties scannerProps, EnvironmentInformation env, GlobalAnalysisMode globalMode, System2 system) { + String url = defaultIfBlank(scannerProps.property("sonar.host.url"), "http://localhost:9000"); + HttpConnector.Builder connectorBuilder = HttpConnector.newBuilder(); + + String timeoutSec = defaultIfBlank(scannerProps.property(READ_TIMEOUT_SEC_PROPERTY), valueOf(DEFAULT_READ_TIMEOUT_SEC)); + String token = defaultIfBlank(system.envVariable("SONAR_TOKEN"), null); + String login = defaultIfBlank(scannerProps.property(CoreProperties.LOGIN), token); + connectorBuilder + .readTimeoutMilliseconds(parseInt(timeoutSec) * 1_000) + .connectTimeoutMilliseconds(CONNECT_TIMEOUT_MS) + .userAgent(env.toString()) + .url(url) + .credentials(login, scannerProps.property(CoreProperties.PASSWORD)); + + // OkHttp detect 'http.proxyHost' java property, but credentials should be filled + final String proxyUser = System.getProperty("http.proxyUser", ""); + if (!proxyUser.isEmpty()) { + connectorBuilder.proxyCredentials(proxyUser, System.getProperty("http.proxyPassword")); } - return wsClient; + + return new DefaultScannerWsClient(WsClientFactories.getDefault().newClient(connectorBuilder.build()), login != null, globalMode); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java new file mode 100644 index 00000000000..0e1a3ad9d31 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java @@ -0,0 +1,231 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.bootstrap; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import javax.annotation.CheckForNull; +import org.jetbrains.annotations.Nullable; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.utils.System2; +import org.sonar.core.platform.ComponentKeys; +import org.sonar.core.platform.Container; +import org.sonar.core.platform.ExtensionContainer; +import org.sonar.core.platform.PluginInfo; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator; + +import static java.util.Collections.emptyList; +import static java.util.Optional.ofNullable; + +public class SpringComponentContainer implements ExtensionContainer { + protected final AnnotationConfigApplicationContext context; + @Nullable + protected final SpringComponentContainer parent; + + private final PropertyDefinitions propertyDefinitions; + private final ComponentKeys componentKeys = new ComponentKeys(); + + protected SpringComponentContainer() { + this(null, new PropertyDefinitions(System2.INSTANCE), emptyList()); + } + + protected SpringComponentContainer(List<?> externalExtensions) { + this(null, new PropertyDefinitions(System2.INSTANCE), externalExtensions); + } + + protected SpringComponentContainer(SpringComponentContainer parent) { + this(parent, parent.propertyDefinitions, emptyList()); + } + + private SpringComponentContainer(@Nullable SpringComponentContainer parent, PropertyDefinitions propertyDefinitions, List<?> externalExtensions) { + this.parent = parent; + this.propertyDefinitions = propertyDefinitions; + this.context = new AnnotationConfigApplicationContext(new PriorityBeanFactory()); + // it won't set the name of beans created with @Bean annotated methods + this.context.setBeanNameGenerator(new FullyQualifiedAnnotationBeanNameGenerator()); + if (parent != null) { + context.setParent(parent.context); + } + add(this); + add(new StartableBeanPostProcessor()); + add(externalExtensions); + add(propertyDefinitions); + } + + /** + * Beans need to have a unique name, otherwise they'll override each other. + * The strategy is: + * - For classes, use the fully qualified class name as the name of the bean + * - For instances, use the FQCN + toString() + * - If the object is a collection, iterate through the elements and apply the same strategy for each of them + */ + @Override + public Container add(Object... objects) { + for (Object o : objects) { + if (o instanceof Class) { + Class<?> clazz = (Class<?>) o; + context.registerBean(clazz); + } else if (o instanceof Iterable) { + add(Iterables.toArray((Iterable<?>) o, Object.class)); + } else { + registerInstance(o); + } + } + return this; + } + + private <T> void registerInstance(T instance) { + Supplier<T> supplier = () -> instance; + Class<T> clazz = (Class<T>) instance.getClass(); + context.registerBean(componentKeys.ofInstance(instance), clazz, supplier); + declareExtension("", instance); + } + + /** + * Extensions are usually added by plugins and we assume they don't support any injection-related annotations. + * Spring contexts supporting annotations will fail if multiple constructors are present without any annotations indicating which one to use for injection. + * For that reason, we need to create the beans ourselves, using ClassDerivedBeanDefinition, which will declare that all constructors can be used for injection. + */ + private Container addExtension(Object o) { + if (o instanceof Class) { + Class<?> clazz = (Class<?>) o; + ClassDerivedBeanDefinition bd = new ClassDerivedBeanDefinition(clazz); + context.registerBeanDefinition(clazz.getName(), bd); + } else if (o instanceof Iterable) { + ((Iterable<?>) o).forEach(this::addExtension); + } else { + ClassDerivedBeanDefinition bd = new ClassDerivedBeanDefinition(o.getClass()); + bd.setInstanceSupplier(() -> o); + context.registerBeanDefinition(componentKeys.ofInstance(o), bd); + } + return this; + } + + @Override + public Container addSingletons(Iterable<?> components) { + return add(components); + } + + @Override + public <T> T getComponentByType(Class<T> type) { + try { + return context.getBean(type); + } catch (Exception t) { + throw new IllegalStateException("Unable to load component " + type, t); + } + } + + @Override + public <T> List<T> getComponentsByType(Class<T> type) { + try { + return new ArrayList<>(context.getBeansOfType(type).values()); + } catch (Exception t) { + throw new IllegalStateException("Unable to load components " + type, t); + } + } + + public void execute() { + RuntimeException r = null; + try { + startComponents(); + } catch (RuntimeException e) { + r = e; + } finally { + try { + stopComponents(); + } catch (RuntimeException e) { + if (r == null) { + r = e; + } + } + } + if (r != null) { + throw r; + } + } + + public SpringComponentContainer startComponents() { + doBeforeStart(); + context.refresh(); + doAfterStart(); + return this; + } + + public SpringComponentContainer stopComponents() { + if (context.isActive()) { + context.close(); + } + return this; + } + + public SpringComponentContainer createChild() { + return new SpringComponentContainer(this); + } + + @Override + @CheckForNull + public SpringComponentContainer getParent() { + return parent; + } + + @Override + public SpringComponentContainer addExtension(@Nullable PluginInfo pluginInfo, Object extension) { + addExtension(extension); + declareExtension(pluginInfo, extension); + return this; + } + + @Override + public SpringComponentContainer addExtension(@Nullable String defaultCategory, Object extension) { + addExtension(extension); + declareExtension(defaultCategory, extension); + return this; + } + + @Override + public SpringComponentContainer declareExtension(@Nullable PluginInfo pluginInfo, Object extension) { + declareExtension(pluginInfo != null ? pluginInfo.getName() : "", extension); + return this; + } + + @Override + public SpringComponentContainer declareExtension(@Nullable String defaultCategory, Object extension) { + this.propertyDefinitions.addComponent(extension, ofNullable(defaultCategory).orElse("")); + return this; + } + + /** + * This method aims to be overridden + */ + protected void doBeforeStart() { + // nothing + } + + /** + * This method aims to be overridden + */ + protected void doAfterStart() { + // nothing + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java index 84e3f95b72c..fb0f25eaf76 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java @@ -22,13 +22,13 @@ package org.sonar.scanner.bootstrap; import java.time.Clock; import java.util.List; import java.util.Map; +import javax.annotation.Priority; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; import org.sonar.api.Plugin; import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; -import org.sonar.api.SonarRuntime; import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.MessageException; @@ -39,7 +39,6 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.extension.CoreExtensionRepositoryImpl; import org.sonar.core.extension.CoreExtensionsLoader; -import org.sonar.core.platform.ComponentContainer; import org.sonar.core.platform.PluginClassLoader; import org.sonar.core.platform.PluginClassloaderFactory; import org.sonar.core.platform.PluginInfo; @@ -51,30 +50,26 @@ import org.sonar.scanner.notifications.DefaultAnalysisWarnings; import org.sonar.scanner.platform.DefaultServer; import org.sonar.scanner.repository.DefaultMetricsRepositoryLoader; import org.sonar.scanner.repository.DefaultNewCodePeriodLoader; -import org.sonar.scanner.repository.MetricsRepositoryLoader; import org.sonar.scanner.repository.MetricsRepositoryProvider; -import org.sonar.scanner.repository.NewCodePeriodLoader; import org.sonar.scanner.repository.settings.DefaultGlobalSettingsLoader; -import org.sonar.scanner.repository.settings.GlobalSettingsLoader; -import org.sonar.scanner.scan.ProjectScanContainer; +import org.sonar.scanner.scan.SpringProjectScanContainer; -public class GlobalContainer extends ComponentContainer { - private static final Logger LOG = Loggers.get(GlobalContainer.class); +@Priority(3) +public class SpringGlobalContainer extends SpringComponentContainer { + private static final Logger LOG = Loggers.get(SpringGlobalContainer.class); private final Map<String, String> scannerProperties; - private GlobalContainer(Map<String, String> scannerProperties) { - super(); + private SpringGlobalContainer(Map<String, String> scannerProperties, List<?> addedExternally) { + super(addedExternally); this.scannerProperties = scannerProperties; } - public static GlobalContainer create(Map<String, String> scannerProperties, List<?> extensions) { - GlobalContainer container = new GlobalContainer(scannerProperties); - container.add(extensions); - return container; + public static SpringGlobalContainer create(Map<String, String> scannerProperties, List<?> extensions) { + return new SpringGlobalContainer(scannerProperties, extensions); } @Override - protected void doBeforeStart() { + public void doBeforeStart() { ScannerProperties rawScannerProperties = new ScannerProperties(scannerProperties); GlobalAnalysisMode globalMode = new GlobalAnalysisMode(rawScannerProperties); add(rawScannerProperties); @@ -100,20 +95,22 @@ public class GlobalContainer extends ComponentContainer { new ScannerWsClientProvider(), DefaultServer.class, new GlobalTempFolderProvider(), - DefaultHttpDownloader.class, analysisWarnings, UriReader.class, PluginFiles.class, System2.INSTANCE, Clock.systemDefaultZone(), new MetricsRepositoryProvider(), - UuidFactoryImpl.INSTANCE); - addIfMissing(SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition), SonarRuntime.class); - addIfMissing(ScannerPluginInstaller.class, PluginInstaller.class); - add(CoreExtensionRepositoryImpl.class, CoreExtensionsLoader.class, ScannerCoreExtensionsInstaller.class); - addIfMissing(DefaultGlobalSettingsLoader.class, GlobalSettingsLoader.class); - addIfMissing(DefaultNewCodePeriodLoader.class, NewCodePeriodLoader.class); - addIfMissing(DefaultMetricsRepositoryLoader.class, MetricsRepositoryLoader.class); + UuidFactoryImpl.INSTANCE, + DefaultHttpDownloader.class, + SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition), + ScannerPluginInstaller.class, + CoreExtensionRepositoryImpl.class, + CoreExtensionsLoader.class, + ScannerCoreExtensionsInstaller.class, + DefaultGlobalSettingsLoader.class, + DefaultNewCodePeriodLoader.class, + DefaultMetricsRepositoryLoader.class); } @Override @@ -133,7 +130,7 @@ public class GlobalContainer extends ComponentContainer { if (!analysisMode.equals("publish")) { throw MessageException.of("The preview mode, along with the 'sonar.analysis.mode' parameter, is no more supported. You should stop using this parameter."); } - new ProjectScanContainer(this).execute(); + new SpringProjectScanContainer(this).execute(); LOG.info("Analysis total time: {}", formatTime(System.currentTimeMillis() - startTime)); } @@ -147,8 +144,7 @@ public class GlobalContainer extends ComponentContainer { } private void loadCoreExtensions() { - CoreExtensionsLoader loader = getComponentByType(CoreExtensionsLoader.class); - loader.load(); + getComponentByType(CoreExtensionsLoader.class).load(); } static String formatTime(long time) { @@ -166,5 +162,4 @@ public class GlobalContainer extends ComponentContainer { } return String.format(format, h, m, s, ms); } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java new file mode 100644 index 00000000000..3bb4cb5570a --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.bootstrap; + +import org.sonar.api.Startable; +import org.sonar.api.utils.log.Loggers; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; +import org.springframework.lang.Nullable; + +public class StartableBeanPostProcessor implements DestructionAwareBeanPostProcessor { + @Override + @Nullable + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Startable) { + ((Startable) bean).start(); + } else if (bean instanceof org.picocontainer.Startable) { + ((org.picocontainer.Startable) bean).start(); + } + return bean; + } + + @Override + public boolean requiresDestruction(Object bean) { + return (bean instanceof Startable) || (bean instanceof org.picocontainer.Startable) || (bean instanceof AutoCloseable); + } + + @Override + public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { + try { + if (bean instanceof Startable) { + ((Startable) bean).stop(); + } else if (bean instanceof org.picocontainer.Startable) { + ((org.picocontainer.Startable) bean).stop(); + } else if (bean instanceof AutoCloseable) { + ((AutoCloseable) bean).close(); + } + } catch (Exception e) { + Loggers.get(StartableBeanPostProcessor.class) + .warn("Dispose of component {} failed", bean.getClass().getCanonicalName(), e); + } + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java index 12cb331a398..ebb55b9910c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java @@ -23,17 +23,18 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.config.Configuration; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.springframework.context.annotation.Bean; -public class CiConfigurationProvider extends ProviderAdapter { +public class CiConfigurationProvider { private static final Logger LOG = Loggers.get(CiConfigurationProvider.class); private static final String PROP_DISABLED = "sonar.ci.autoconfig.disabled"; + @Bean("CiConfiguration") public CiConfiguration provide(Configuration configuration, CiVendor[] ciVendors) { boolean disabled = configuration.getBoolean(PROP_DISABLED).orElse(false); if (disabled) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java index 017051f4118..41c6ec4102b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeoutException; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; +import javax.inject.Inject; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.internal.DefaultInputComponent; import org.sonar.api.batch.fs.internal.DefaultInputFile; @@ -71,12 +72,12 @@ public class CpdExecutor { private int count = 0; private int total; + @Inject public CpdExecutor(CpdSettings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache) { this(settings, index, publisher, inputComponentCache, Executors.newSingleThreadExecutor()); } - public CpdExecutor(CpdSettings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache, - ExecutorService executorService) { + public CpdExecutor(CpdSettings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache, ExecutorService executorService) { this.settings = settings; this.index = index; this.publisher = publisher; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java index ecaaa7d8f1b..1d850c39a4d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java @@ -25,6 +25,7 @@ import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.api.scan.issue.filter.IssueFilter; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.scanner.protocol.output.ScannerReport; +import org.springframework.beans.factory.annotation.Autowired; /** * @deprecated since 7.6, {@link IssueFilter} is deprecated @@ -34,11 +35,13 @@ public class IssueFilters { private final IssueFilterChain filterChain; private final DefaultInputProject project; + @Autowired(required = false) public IssueFilters(DefaultInputProject project, IssueFilter[] exclusionFilters) { this.project = project; this.filterChain = new DefaultIssueFilterChain(exclusionFilters); } + @Autowired(required = false) public IssueFilters(DefaultInputProject project) { this(project, new IssueFilter[0]); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObserver.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObserver.java index 3fe40990f84..77fac1555cc 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObserver.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObserver.java @@ -21,13 +21,13 @@ package org.sonar.scanner.mediumtest; import org.sonar.api.ExtensionPoint; import org.sonar.api.scanner.ScannerSide; -import org.sonar.scanner.scan.ProjectScanContainer; +import org.sonar.scanner.scan.SpringProjectScanContainer; @ScannerSide @ExtensionPoint @FunctionalInterface public interface AnalysisObserver { - void analysisCompleted(ProjectScanContainer container); + void analysisCompleted(SpringProjectScanContainer container); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObservers.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObservers.java index 088c15e175b..9fe59b99499 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObservers.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisObservers.java @@ -19,22 +19,18 @@ */ package org.sonar.scanner.mediumtest; -import org.sonar.scanner.scan.ProjectScanContainer; +import org.sonar.scanner.scan.SpringProjectScanContainer; public class AnalysisObservers { - private AnalysisObserver[] observers; - private ProjectScanContainer projectScanContainer; + private final AnalysisObserver[] observers; + private final SpringProjectScanContainer projectScanContainer; - public AnalysisObservers(ProjectScanContainer projectScanContainer, AnalysisObserver... observers) { + public AnalysisObservers(SpringProjectScanContainer projectScanContainer, AnalysisObserver... observers) { this.projectScanContainer = projectScanContainer; this.observers = observers; } - public AnalysisObservers(ProjectScanContainer projectScanContainer) { - this(projectScanContainer, new AnalysisObserver[0]); - } - public void notifyEndOfScanTask() { for (AnalysisObserver analysisObserver : observers) { analysisObserver.analysisCompleted(projectScanContainer); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java index e9eaaf6c84b..1f002bf75bd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java @@ -43,7 +43,7 @@ import org.sonar.scanner.protocol.output.ScannerReport.Symbol; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.report.ReportPublisher; import org.sonar.scanner.report.ScannerReportUtils; -import org.sonar.scanner.scan.ProjectScanContainer; +import org.sonar.scanner.scan.SpringProjectScanContainer; import org.sonar.scanner.scan.filesystem.InputComponentStore; public class AnalysisResult implements AnalysisObserver { @@ -55,7 +55,7 @@ public class AnalysisResult implements AnalysisObserver { private ScannerReportReader reader; @Override - public void analysisCompleted(ProjectScanContainer container) { + public void analysisCompleted(SpringProjectScanContainer container) { LOG.info("Store analysis results in memory for later assertions in medium test"); ReportPublisher reportPublisher = container.getComponentByType(ReportPublisher.class); reader = new ScannerReportReader(reportPublisher.getReportDir().toFile()); @@ -69,7 +69,7 @@ public class AnalysisResult implements AnalysisObserver { return reader; } - private void storeFs(ProjectScanContainer container) { + private void storeFs(SpringProjectScanContainer container) { InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class); for (InputFile inputPath : inputFileCache.inputFiles()) { inputFilesByKeys.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java index ea08a9ae8d5..5800b912a7b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java @@ -24,11 +24,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.Priority; import org.sonar.api.Plugin; import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.PluginInstaller; import org.sonar.scanner.bootstrap.ScannerPlugin; +@Priority(1) public class FakePluginInstaller implements PluginInstaller { private final Map<String, ScannerPlugin> pluginsByKeys = new HashMap<>(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java index a18b95b06d5..4ec321fd5e0 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java @@ -23,7 +23,7 @@ import java.io.InputStream; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.EnumSet; -import org.picocontainer.Startable; +import org.sonar.api.Startable; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java index 2bf6e977297..e5abefb3a4f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java @@ -42,8 +42,7 @@ public class ContextPropertiesPublisher implements ReportPublisherStep { private final ScmConfiguration scmConfiguration; private final CiConfiguration ciConfiguration; - public ContextPropertiesPublisher(ContextPropertiesCache cache, DefaultConfiguration config, ScmConfiguration scmConfiguration, - CiConfiguration ciConfiguration) { + public ContextPropertiesPublisher(ContextPropertiesCache cache, DefaultConfiguration config, ScmConfiguration scmConfiguration, CiConfiguration ciConfiguration) { this.cache = cache; this.config = config; this.scmConfiguration = scmConfiguration; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java index 5c2bbb19e49..abf89bae8e5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java @@ -33,7 +33,7 @@ import java.util.Map; import javax.annotation.Nullable; import okhttp3.HttpUrl; import org.apache.commons.io.FileUtils; -import org.picocontainer.Startable; +import org.sonar.api.Startable; import org.sonar.api.platform.Server; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; @@ -97,13 +97,13 @@ public class ReportPublisher implements Startable { this.branchConfiguration = branchConfiguration; this.properties = properties; this.ceTaskReportDataHolder = ceTaskReportDataHolder; + this.reportDir = moduleHierarchy.root().getWorkDir().resolve("scanner-report"); + this.writer = new ScannerReportWriter(reportDir.toFile()); + this.reader = new ScannerReportReader(reportDir.toFile()); } @Override public void start() { - reportDir = moduleHierarchy.root().getWorkDir().resolve("scanner-report"); - writer = new ScannerReportWriter(reportDir.toFile()); - reader = new ScannerReportReader(reportDir.toFile()); contextPublisher.init(writer); if (!analysisMode.isMediumTest()) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/MetricsRepositoryProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/MetricsRepositoryProvider.java index d5685073e5e..54ba26c6f4f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/MetricsRepositoryProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/MetricsRepositoryProvider.java @@ -19,23 +19,21 @@ */ package org.sonar.scanner.repository; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; +import org.springframework.context.annotation.Bean; -public class MetricsRepositoryProvider extends ProviderAdapter { +public class MetricsRepositoryProvider { private static final Logger LOG = Loggers.get(MetricsRepositoryProvider.class); private static final String LOG_MSG = "Load metrics repository"; - private MetricsRepository metricsRepository; + @Bean("MetricsRepository") public MetricsRepository provide(MetricsRepositoryLoader loader) { - if (metricsRepository == null) { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - metricsRepository = loader.load(); - profiler.stopInfo(); - } + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + MetricsRepository metricsRepository = loader.load(); + profiler.stopInfo(); return metricsRepository; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java index 37bb0d1c04e..374d4ae0934 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java @@ -19,25 +19,22 @@ */ package org.sonar.scanner.repository; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.bootstrap.ScannerProperties; import org.sonar.scanner.rule.QualityProfiles; +import org.springframework.context.annotation.Bean; -public class QualityProfilesProvider extends ProviderAdapter { +public class QualityProfilesProvider { private static final Logger LOG = Loggers.get(QualityProfilesProvider.class); private static final String LOG_MSG = "Load quality profiles"; - private QualityProfiles profiles = null; + @Bean("QualityProfiles") public QualityProfiles provide(QualityProfileLoader loader, ScannerProperties props) { - if (this.profiles == null) { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - profiles = new QualityProfiles(loader.load(props.getProjectKey())); - profiler.stopInfo(); - } - + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + QualityProfiles profiles = new QualityProfiles(loader.load(props.getProjectKey())); + profiler.stopInfo(); return profiles; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/language/DefaultLanguagesRepository.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/language/DefaultLanguagesRepository.java index 9a5f8fdffdf..acfd8a0a455 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/language/DefaultLanguagesRepository.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/language/DefaultLanguagesRepository.java @@ -24,7 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import javax.annotation.CheckForNull; import javax.annotation.concurrent.Immutable; -import org.picocontainer.Startable; +import org.sonar.api.Startable; import org.sonar.api.resources.Languages; /** diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoader.java index b0bc4886986..07f3a3c1aa2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoader.java @@ -20,11 +20,13 @@ package org.sonar.scanner.repository.settings; import java.util.Map; +import javax.inject.Inject; import org.sonar.scanner.bootstrap.DefaultScannerWsClient; public class DefaultGlobalSettingsLoader extends AbstractSettingsLoader implements GlobalSettingsLoader { - public DefaultGlobalSettingsLoader(final DefaultScannerWsClient wsClient) { + @Inject + public DefaultGlobalSettingsLoader(DefaultScannerWsClient wsClient) { super(wsClient); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/ActiveRulesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/ActiveRulesProvider.java index e6731d5df87..71ecf104b9b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/ActiveRulesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/ActiveRulesProvider.java @@ -25,7 +25,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.rule.LoadedActiveRule; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.DefaultActiveRules; @@ -34,23 +33,22 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; +import org.springframework.context.annotation.Bean; /** * Loads the rules that are activated on the Quality profiles * used by the current project and builds {@link org.sonar.api.batch.rule.ActiveRules}. */ -public class ActiveRulesProvider extends ProviderAdapter { +public class ActiveRulesProvider { private static final Logger LOG = Loggers.get(ActiveRulesProvider.class); private static final String LOG_MSG = "Load active rules"; - private DefaultActiveRules singleton = null; + @Bean("ActiveRules") public DefaultActiveRules provide(ActiveRulesLoader loader, QualityProfiles qProfiles) { - if (singleton == null) { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - singleton = load(loader, qProfiles); - profiler.stopInfo(); - } - return singleton; + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + DefaultActiveRules activeRules = load(loader, qProfiles); + profiler.stopInfo(); + return activeRules; } private static DefaultActiveRules load(ActiveRulesLoader loader, QualityProfiles qProfiles) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/RulesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/RulesProvider.java index e2f82b3d165..9c05e4fece3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/RulesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/RulesProvider.java @@ -20,29 +20,22 @@ package org.sonar.scanner.rule; import java.util.List; -import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.rule.internal.NewRule; import org.sonar.api.batch.rule.Rules; +import org.sonar.api.batch.rule.internal.NewRule; import org.sonar.api.batch.rule.internal.RulesBuilder; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonarqube.ws.Rules.ListResponse.Rule; +import org.springframework.context.annotation.Bean; -public class RulesProvider extends ProviderAdapter { +public class RulesProvider { private static final Logger LOG = Loggers.get(RulesProvider.class); private static final String LOG_MSG = "Load server rules"; - private Rules singleton = null; + @Bean("Rules") public Rules provide(RulesLoader ref) { - if (singleton == null) { - singleton = load(ref); - } - return singleton; - } - - private static Rules load(RulesLoader ref) { Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); List<Rule> loadedRules = ref.load(); RulesBuilder builder = new RulesBuilder(); @@ -54,7 +47,6 @@ public class RulesProvider extends ProviderAdapter { } profiler.stopInfo(); - return builder.build(); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java index 940e0ac9dd8..8915a7ab672 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java @@ -22,32 +22,31 @@ package org.sonar.scanner.scan; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; +import org.springframework.context.annotation.Bean; -public class InputModuleHierarchyProvider extends ProviderAdapter { +public class InputModuleHierarchyProvider { private static final Logger LOG = Loggers.get(InputModuleHierarchyProvider.class); - private DefaultInputModuleHierarchy hierarchy = null; - - public DefaultInputModuleHierarchy provide(ScannerComponentIdGenerator scannerComponentIdGenerator, DefaultInputProject project) { - if (hierarchy == null) { - LOG.debug("Creating module hierarchy"); - DefaultInputModule root = createModule(project.definition(), project.scannerId()); - Map<DefaultInputModule, DefaultInputModule> parents = createChildren(root, scannerComponentIdGenerator, new HashMap<>()); - if (parents.isEmpty()) { - hierarchy = new DefaultInputModuleHierarchy(root); - } else { - hierarchy = new DefaultInputModuleHierarchy(root, parents); - } + @Bean("DefaultInputModuleHierarchy") + public DefaultInputModuleHierarchy provide(ScannerComponentIdGenerator scannerComponentIdGenerator, WorkDirectoriesInitializer workDirectoriesInit, DefaultInputProject project) { + LOG.debug("Creating module hierarchy"); + DefaultInputModule root = createModule(project.definition(), project.scannerId()); + Map<DefaultInputModule, DefaultInputModule> parents = createChildren(root, scannerComponentIdGenerator, new HashMap<>()); + DefaultInputModuleHierarchy inputModuleHierarchy; + if (parents.isEmpty()) { + inputModuleHierarchy = new DefaultInputModuleHierarchy(root); + } else { + inputModuleHierarchy = new DefaultInputModuleHierarchy(root, parents); } - return hierarchy; + workDirectoriesInit.execute(inputModuleHierarchy); + return inputModuleHierarchy; } private static Map<DefaultInputModule, DefaultInputModule> createChildren(DefaultInputModule parent, ScannerComponentIdGenerator scannerComponentIdGenerator, diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java index 8bcb781e23f..b5629ce69ef 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java @@ -20,36 +20,32 @@ package org.sonar.scanner.scan; import java.util.Locale; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectReactor; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; +import org.springframework.context.annotation.Bean; -public class InputProjectProvider extends ProviderAdapter { - +public class InputProjectProvider { private static final Logger LOG = Loggers.get(InputProjectProvider.class); - private DefaultInputProject project = null; - + @Bean("DefaultInputProject") public DefaultInputProject provide(ProjectBuildersExecutor projectBuildersExecutor, ProjectReactorValidator validator, ProjectReactor projectReactor, ScannerComponentIdGenerator scannerComponentIdGenerator) { - if (project == null) { - // 1 Apply project builders - projectBuildersExecutor.execute(projectReactor); + // 1 Apply project builders + projectBuildersExecutor.execute(projectReactor); - // 2 Validate final reactor - validator.validate(projectReactor); + // 2 Validate final reactor + validator.validate(projectReactor); - // 3 Create project - project = new DefaultInputProject(projectReactor.getRoot(), scannerComponentIdGenerator.getAsInt()); + // 3 Create project + DefaultInputProject project = new DefaultInputProject(projectReactor.getRoot(), scannerComponentIdGenerator.getAsInt()); - LOG.info("Project key: {}", project.key()); - LOG.info("Base dir: {}", project.getBaseDir().toAbsolutePath().toString()); - LOG.info("Working dir: {}", project.getWorkDir().toAbsolutePath().toString()); - LOG.debug("Project global encoding: {}, default locale: {}", project.getEncoding().displayName(), Locale.getDefault()); - } + LOG.info("Project key: {}", project.key()); + LOG.info("Base dir: {}", project.getBaseDir().toAbsolutePath().toString()); + LOG.info("Working dir: {}", project.getWorkDir().toAbsolutePath().toString()); + LOG.debug("Project global encoding: {}, default locale: {}", project.getEncoding().displayName(), Locale.getDefault()); return project; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java new file mode 100644 index 00000000000..d1c3d972350 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.scan; + +import java.util.List; +import java.util.Optional; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.springframework.context.annotation.Bean; + +public class LanguagesProvider { + @Bean("Languages") + public Languages provide(Optional<List<Language>> languages) { + if (languages.isEmpty()) { + return new Languages(); + } + return new Languages(languages.get().toArray(new Language[0])); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfiguration.java index 65b4a945f91..3abef362efb 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfiguration.java @@ -20,14 +20,12 @@ package org.sonar.scanner.scan; import java.util.Map; -import org.sonar.api.config.internal.Encryption; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.internal.Encryption; import org.sonar.scanner.config.DefaultConfiguration; public class ModuleConfiguration extends DefaultConfiguration { - public ModuleConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> props) { super(propertyDefinitions, encryption, props); } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java index 1728d29537b..5cb88b0e7b3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java @@ -23,28 +23,22 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; -import org.sonar.api.batch.fs.internal.DefaultInputModule; - -public class ModuleConfigurationProvider extends ProviderAdapter { - - private ModuleConfiguration moduleConfiguration; +import org.springframework.context.annotation.Bean; +public class ModuleConfigurationProvider { + @Bean("ModuleConfiguration") public ModuleConfiguration provide(GlobalConfiguration globalConfig, DefaultInputModule module, GlobalServerSettings globalServerSettings, ProjectServerSettings projectServerSettings) { - if (moduleConfiguration == null) { - - Map<String, String> settings = new LinkedHashMap<>(); - settings.putAll(globalServerSettings.properties()); - settings.putAll(projectServerSettings.properties()); - addScannerSideProperties(settings, module.definition()); + Map<String, String> settings = new LinkedHashMap<>(); + settings.putAll(globalServerSettings.properties()); + settings.putAll(projectServerSettings.properties()); + addScannerSideProperties(settings, module.definition()); - moduleConfiguration = new ModuleConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); - } - return moduleConfiguration; + return new ModuleConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); } private static void addScannerSideProperties(Map<String, String> settings, ProjectDefinition project) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java index 69974fccd06..517e995af4f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java @@ -19,7 +19,7 @@ */ package org.sonar.scanner.scan; -import org.picocontainer.Startable; +import org.sonar.api.Startable; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.scan.filesystem.InputComponentStore; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java index c4d50aa3959..a6cdc6b853f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java @@ -22,6 +22,7 @@ package org.sonar.scanner.scan; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import javax.annotation.Priority; import org.sonar.api.config.internal.Settings; import static java.util.Objects.requireNonNull; @@ -30,6 +31,7 @@ import static java.util.Objects.requireNonNull; * @deprecated since 6.5 {@link ModuleConfiguration} used to be mutable, so keep a mutable copy for backward compatibility. */ @Deprecated +@Priority(1) public class MutableModuleSettings extends Settings { private final Map<String, String> properties = new HashMap<>(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectReactorProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectReactorProvider.java index 242eec3bd58..7bdc9a2bd4d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectReactorProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectReactorProvider.java @@ -19,16 +19,12 @@ */ package org.sonar.scanner.scan; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectReactor; +import org.springframework.context.annotation.Bean; -public class MutableProjectReactorProvider extends ProviderAdapter { - private ProjectReactor reactor = null; - +public class MutableProjectReactorProvider { + @Bean("ProjectReactor") public ProjectReactor provide(ProjectReactorBuilder builder) { - if (reactor == null) { - reactor = builder.execute(); - } - return reactor; + return builder.execute(); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java index cccd0a1c1d6..a521aa96a45 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java @@ -25,12 +25,15 @@ import java.util.Optional; import org.sonar.api.config.internal.Settings; import org.sonar.scanner.bootstrap.GlobalConfiguration; +import javax.annotation.Priority; + import static java.util.Objects.requireNonNull; /** * @deprecated since 6.5 {@link ProjectConfiguration} used to be mutable, so keep a mutable copy for backward compatibility. */ @Deprecated +@Priority(2) public class MutableProjectSettings extends Settings { private final Map<String, String> properties = new HashMap<>(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectBuildersExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectBuildersExecutor.java index b45e9f5cfa8..2d214650ce7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectBuildersExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectBuildersExecutor.java @@ -28,6 +28,7 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.bootstrap.GlobalConfiguration; +import org.springframework.beans.factory.annotation.Autowired; public class ProjectBuildersExecutor { @@ -36,11 +37,13 @@ public class ProjectBuildersExecutor { private final GlobalConfiguration globalConfig; private final ProjectBuilder[] projectBuilders; + @Autowired(required = false) public ProjectBuildersExecutor(GlobalConfiguration globalConfig, ProjectBuilder... projectBuilders) { this.globalConfig = globalConfig; this.projectBuilders = projectBuilders; } + @Autowired(required = false) public ProjectBuildersExecutor(GlobalConfiguration globalConfig) { this(globalConfig, new ProjectBuilder[0]); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfiguration.java index 390ee96e80f..80a1e1fad78 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfiguration.java @@ -20,14 +20,12 @@ package org.sonar.scanner.scan; import java.util.Map; -import org.sonar.api.config.internal.Encryption; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.internal.Encryption; import org.sonar.scanner.config.DefaultConfiguration; public class ProjectConfiguration extends DefaultConfiguration { - public ProjectConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, Map<String, String> props) { super(propertyDefinitions, encryption, props); } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java index 8c79c3965e2..d20ff578439 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java @@ -21,27 +21,22 @@ package org.sonar.scanner.scan; import java.util.LinkedHashMap; import java.util.Map; -import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; -import org.sonar.api.batch.fs.internal.DefaultInputProject; - -public class ProjectConfigurationProvider extends ProviderAdapter { - - private ProjectConfiguration projectConfig; +import org.springframework.context.annotation.Bean; +public class ProjectConfigurationProvider { + @Bean("ProjectConfiguration") public ProjectConfiguration provide(DefaultInputProject project, GlobalConfiguration globalConfig, GlobalServerSettings globalServerSettings, ProjectServerSettings projectServerSettings, MutableProjectSettings projectSettings) { - if (projectConfig == null) { - - Map<String, String> settings = new LinkedHashMap<>(); - settings.putAll(globalServerSettings.properties()); - settings.putAll(projectServerSettings.properties()); - settings.putAll(project.properties()); + Map<String, String> settings = new LinkedHashMap<>(); + settings.putAll(globalServerSettings.properties()); + settings.putAll(projectServerSettings.properties()); + settings.putAll(project.properties()); - projectConfig = new ProjectConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); - projectSettings.complete(projectConfig); - } + ProjectConfiguration projectConfig = new ProjectConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), settings); + projectSettings.complete(projectConfig); return projectConfig; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java index 1e9776e92d0..8463396f4f8 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java @@ -23,7 +23,7 @@ import java.io.IOException; import java.nio.channels.OverlappingFileLockException; import java.nio.file.Files; import java.nio.file.Path; -import org.picocontainer.Startable; +import org.sonar.api.Startable; import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; public class ProjectLock implements Startable { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java index f32a52cb7bf..6b4f05f9d25 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java @@ -29,6 +29,7 @@ import org.sonar.api.utils.MessageException; import org.sonar.core.component.ComponentKeys; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.scan.branch.BranchParamsValidator; +import org.springframework.beans.factory.annotation.Autowired; import static java.lang.String.format; import static java.util.Objects.nonNull; @@ -52,11 +53,13 @@ public class ProjectReactorValidator { @Nullable private final BranchParamsValidator branchParamsValidator; + @Autowired(required = false) public ProjectReactorValidator(GlobalConfiguration settings, @Nullable BranchParamsValidator branchParamsValidator) { this.settings = settings; this.branchParamsValidator = branchParamsValidator; } + @Autowired(required = false) public ProjectReactorValidator(GlobalConfiguration settings) { this(settings, null); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java index cc587573010..55516177aa9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java @@ -21,14 +21,14 @@ package org.sonar.scanner.scan; import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.repository.settings.ProjectSettingsLoader; +import org.springframework.context.annotation.Bean; -public class ProjectServerSettingsProvider extends ProviderAdapter { +public class ProjectServerSettingsProvider { private static final Logger LOG = Loggers.get(ProjectConfigurationProvider.class); @@ -37,17 +37,13 @@ public class ProjectServerSettingsProvider extends ProviderAdapter { "Archived Sub-Projects Settings' at project level, and clear the property to prevent the analysis from " + "displaying this warning."; - private ProjectServerSettings singleton = null; - + @Bean("ProjectServerSettings") public ProjectServerSettings provide(ProjectSettingsLoader loader, AnalysisWarnings analysisWarnings) { - if (singleton == null) { - Map<String, String> serverSideSettings = loader.loadProjectSettings(); - if (StringUtils.isNotBlank(serverSideSettings.get(CoreProperties.MODULE_LEVEL_ARCHIVED_SETTINGS))) { - LOG.warn(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); - analysisWarnings.addUnique(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); - } - singleton = new ProjectServerSettings(serverSideSettings); + Map<String, String> serverSideSettings = loader.loadProjectSettings(); + if (StringUtils.isNotBlank(serverSideSettings.get(CoreProperties.MODULE_LEVEL_ARCHIVED_SETTINGS))) { + LOG.warn(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); + analysisWarnings.addUnique(MODULE_LEVEL_ARCHIVED_SETTINGS_WARNING); } - return singleton; + return new ProjectServerSettings(serverSideSettings); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java index c7c17c76799..79a09172a31 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java @@ -19,10 +19,11 @@ */ package org.sonar.scanner.scan; +import javax.annotation.Priority; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.scan.filesystem.FileExclusions; -import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.bootstrap.ExtensionInstaller; +import org.sonar.scanner.bootstrap.SpringComponentContainer; import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem; import org.sonar.scanner.scan.filesystem.ModuleInputComponentStore; import org.sonar.scanner.sensor.ModuleSensorContext; @@ -34,10 +35,11 @@ import static org.sonar.api.batch.InstantiationStrategy.PER_PROJECT; import static org.sonar.scanner.bootstrap.ExtensionUtils.isDeprecatedScannerSide; import static org.sonar.scanner.bootstrap.ExtensionUtils.isInstantiationStrategy; -public class ModuleScanContainer extends ComponentContainer { +@Priority(1) +public class SpringModuleScanContainer extends SpringComponentContainer { private final DefaultInputModule module; - public ModuleScanContainer(ProjectScanContainer parent, DefaultInputModule module) { + public SpringModuleScanContainer(SpringComponentContainer parent, DefaultInputModule module) { super(parent); this.module = module; } @@ -70,7 +72,7 @@ public class ModuleScanContainer extends ComponentContainer { } private void addExtensions() { - ExtensionInstaller pluginInstaller = getComponentByType(ExtensionInstaller.class); + ExtensionInstaller pluginInstaller = parent.getComponentByType(ExtensionInstaller.class); pluginInstaller.install(this, e -> isDeprecatedScannerSide(e) && isInstantiationStrategy(e, PER_PROJECT)); } @@ -78,5 +80,4 @@ public class ModuleScanContainer extends ComponentContainer { protected void doAfterStart() { getComponentByType(ModuleSensorsExecutor.class).execute(); } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java index 954a80ae271..d1d605f42c8 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java @@ -20,12 +20,12 @@ package org.sonar.scanner.scan; import javax.annotation.Nullable; +import javax.annotation.Priority; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.FileMetadata; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.batch.rule.CheckFactory; import org.sonar.api.batch.sensor.issue.internal.DefaultNoSonarFilter; -import org.sonar.api.resources.Languages; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.MessageException; @@ -34,7 +34,6 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.core.config.ScannerProperties; import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.core.metric.ScannerMetrics; -import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.DefaultFileLinesContextFactory; import org.sonar.scanner.ProjectInfo; import org.sonar.scanner.analysis.AnalysisTempFolderProvider; @@ -42,6 +41,7 @@ import org.sonar.scanner.bootstrap.ExtensionInstaller; import org.sonar.scanner.bootstrap.ExtensionMatcher; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.PostJobExtensionDictionary; +import org.sonar.scanner.bootstrap.SpringComponentContainer; import org.sonar.scanner.ci.CiConfigurationProvider; import org.sonar.scanner.ci.vendors.AppVeyor; import org.sonar.scanner.ci.vendors.AwsCodeBuild; @@ -89,20 +89,15 @@ import org.sonar.scanner.report.TestExecutionPublisher; import org.sonar.scanner.repository.ContextPropertiesCache; import org.sonar.scanner.repository.DefaultProjectRepositoriesLoader; import org.sonar.scanner.repository.DefaultQualityProfileLoader; -import org.sonar.scanner.repository.ReferenceBranchSupplier; -import org.sonar.scanner.repository.ProjectRepositoriesLoader; import org.sonar.scanner.repository.ProjectRepositoriesSupplier; -import org.sonar.scanner.repository.QualityProfileLoader; import org.sonar.scanner.repository.QualityProfilesProvider; +import org.sonar.scanner.repository.ReferenceBranchSupplier; import org.sonar.scanner.repository.language.DefaultLanguagesRepository; import org.sonar.scanner.repository.settings.DefaultProjectSettingsLoader; -import org.sonar.scanner.repository.settings.ProjectSettingsLoader; -import org.sonar.scanner.rule.ActiveRulesLoader; import org.sonar.scanner.rule.ActiveRulesProvider; import org.sonar.scanner.rule.DefaultActiveRulesLoader; import org.sonar.scanner.rule.DefaultRulesLoader; import org.sonar.scanner.rule.QProfileVerifier; -import org.sonar.scanner.rule.RulesLoader; import org.sonar.scanner.rule.RulesProvider; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.branch.BranchConfigurationProvider; @@ -138,11 +133,11 @@ import static org.sonar.scanner.bootstrap.ExtensionUtils.isDeprecatedScannerSide import static org.sonar.scanner.bootstrap.ExtensionUtils.isInstantiationStrategy; import static org.sonar.scanner.bootstrap.ExtensionUtils.isScannerSide; -public class ProjectScanContainer extends ComponentContainer { - - private static final Logger LOG = Loggers.get(ProjectScanContainer.class); +@Priority(2) +public class SpringProjectScanContainer extends SpringComponentContainer { + private static final Logger LOG = Loggers.get(SpringProjectScanContainer.class); - public ProjectScanContainer(ComponentContainer globalContainer) { + public SpringProjectScanContainer(SpringComponentContainer globalContainer) { super(globalContainer); } @@ -150,9 +145,6 @@ public class ProjectScanContainer extends ComponentContainer { protected void doBeforeStart() { addScannerExtensions(); addScannerComponents(); - ProjectLock lock = getComponentByType(ProjectLock.class); - lock.tryLock(); - getComponentByType(WorkDirectoriesInitializer.class).execute(); } private void addScannerComponents() { @@ -207,7 +199,7 @@ public class ProjectScanContainer extends ComponentContainer { DefaultMetricFinder.class, // lang - Languages.class, + LanguagesProvider.class, DefaultLanguagesRepository.class, // issue exclusions @@ -298,17 +290,17 @@ public class ProjectScanContainer extends ComponentContainer { add(GitScmSupport.getObjects()); add(SvnScmSupport.getObjects()); - addIfMissing(DefaultProjectSettingsLoader.class, ProjectSettingsLoader.class); - addIfMissing(DefaultRulesLoader.class, RulesLoader.class); - addIfMissing(DefaultActiveRulesLoader.class, ActiveRulesLoader.class); - addIfMissing(DefaultQualityProfileLoader.class, QualityProfileLoader.class); - addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class); + add(DefaultProjectSettingsLoader.class, + DefaultRulesLoader.class, + DefaultActiveRulesLoader.class, + DefaultQualityProfileLoader.class, + DefaultProjectRepositoriesLoader.class); } private void addScannerExtensions() { - getComponentByType(CoreExtensionsInstaller.class) + getParent().getComponentByType(CoreExtensionsInstaller.class) .install(this, noExtensionFilter(), extension -> getScannerProjectExtensionsFilter().accept(extension)); - getComponentByType(ExtensionInstaller.class) + getParent().getComponentByType(ExtensionInstaller.class) .install(this, getScannerProjectExtensionsFilter()); } @@ -323,6 +315,7 @@ public class ProjectScanContainer extends ComponentContainer { @Override protected void doAfterStart() { + getComponentByType(ProjectLock.class).tryLock(); GlobalAnalysisMode analysisMode = getComponentByType(GlobalAnalysisMode.class); InputModuleHierarchy tree = getComponentByType(InputModuleHierarchy.class); ScanProperties properties = getComponentByType(ScanProperties.class); @@ -381,7 +374,7 @@ public class ProjectScanContainer extends ComponentContainer { } void scan(DefaultInputModule module) { - new ModuleScanContainer(this, module).execute(); + new SpringModuleScanContainer(this, module).execute(); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java index ae662ef8e5e..b118a870ff7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java @@ -33,30 +33,23 @@ import org.sonar.scanner.fs.InputModuleHierarchy; * Be careful that sub module work dir might be nested in parent working directory. */ public class WorkDirectoriesInitializer { - - private InputModuleHierarchy moduleHierarchy; - - public WorkDirectoriesInitializer(InputModuleHierarchy moduleHierarchy) { - this.moduleHierarchy = moduleHierarchy; - } - - public void execute() { - cleanAllWorkingDirs(moduleHierarchy.root()); - mkdirsAllWorkingDirs(moduleHierarchy.root()); + public void execute(InputModuleHierarchy moduleHierarchy) { + cleanAllWorkingDirs(moduleHierarchy, moduleHierarchy.root()); + mkdirsAllWorkingDirs(moduleHierarchy, moduleHierarchy.root()); } - private void cleanAllWorkingDirs(DefaultInputModule module) { + private static void cleanAllWorkingDirs(InputModuleHierarchy moduleHierarchy, DefaultInputModule module) { for (DefaultInputModule sub : moduleHierarchy.children(module)) { - cleanAllWorkingDirs(sub); + cleanAllWorkingDirs(moduleHierarchy, sub); } if (Files.exists(module.getWorkDir())) { deleteAllRecursivelyExceptLockFile(module.getWorkDir()); } } - private void mkdirsAllWorkingDirs(DefaultInputModule module) { + private static void mkdirsAllWorkingDirs(InputModuleHierarchy moduleHierarchy, DefaultInputModule module) { for (DefaultInputModule sub : moduleHierarchy.children(module)) { - mkdirsAllWorkingDirs(sub); + mkdirsAllWorkingDirs(moduleHierarchy, sub); } try { Files.createDirectories(module.getWorkDir()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java index 41085f8db9a..87287fadd29 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java @@ -19,31 +19,28 @@ */ package org.sonar.scanner.scan.branch; -import org.picocontainer.annotations.Nullable; -import org.picocontainer.injectors.ProviderAdapter; +import javax.annotation.Nullable; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.scan.ProjectConfiguration; +import org.springframework.context.annotation.Bean; -public class BranchConfigurationProvider extends ProviderAdapter { +public class BranchConfigurationProvider { private static final Logger LOG = Loggers.get(BranchConfigurationProvider.class); private static final String LOG_MSG = "Load branch configuration"; - private BranchConfiguration branchConfiguration = null; - + @Bean("BranchConfiguration") public BranchConfiguration provide(@Nullable BranchConfigurationLoader loader, ProjectConfiguration projectConfiguration, ProjectBranches branches, ProjectPullRequests pullRequests) { - if (branchConfiguration == null) { - if (loader == null) { - branchConfiguration = new DefaultBranchConfiguration(); - } else { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - branchConfiguration = loader.load(projectConfiguration.getProperties(), branches, pullRequests); - profiler.stopInfo(); - } + if (loader == null) { + return new DefaultBranchConfiguration(); + } else { + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + BranchConfiguration branchConfiguration = loader.load(projectConfiguration.getProperties(), branches, pullRequests); + profiler.stopInfo(); + return branchConfiguration; } - return branchConfiguration; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java index d0f8c5f0b35..9e3ad167f27 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java @@ -20,33 +20,27 @@ package org.sonar.scanner.scan.branch; import java.util.Collections; -import org.picocontainer.annotations.Nullable; -import org.picocontainer.injectors.ProviderAdapter; +import javax.annotation.Nullable; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.bootstrap.ScannerProperties; +import org.springframework.context.annotation.Bean; -public class ProjectBranchesProvider extends ProviderAdapter { +public class ProjectBranchesProvider { private static final Logger LOG = Loggers.get(ProjectBranchesProvider.class); private static final String LOG_MSG = "Load project branches"; - private ProjectBranches branches = null; - + @Bean("ProjectBranches") public ProjectBranches provide(@Nullable ProjectBranchesLoader loader, ScannerProperties scannerProperties) { - if (this.branches != null) { - return this.branches; - } - if (loader == null) { - this.branches = new ProjectBranches(Collections.emptyList()); - return this.branches; + return new ProjectBranches(Collections.emptyList()); } Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - this.branches = loader.load(scannerProperties.getProjectKey()); + ProjectBranches branches = loader.load(scannerProperties.getProjectKey()); profiler.stopInfo(); - return this.branches; + return branches; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java index b1bc7c85f97..0b2ebde0fa5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java @@ -20,31 +20,26 @@ package org.sonar.scanner.scan.branch; import java.util.Collections; -import org.picocontainer.injectors.ProviderAdapter; +import javax.annotation.Nullable; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.bootstrap.ScannerProperties; +import org.springframework.context.annotation.Bean; -public class ProjectPullRequestsProvider extends ProviderAdapter { +public class ProjectPullRequestsProvider { private static final Logger LOG = Loggers.get(ProjectPullRequestsProvider.class); private static final String LOG_MSG = "Load project pull requests"; - private ProjectPullRequests pullRequests = null; - - public ProjectPullRequests provide(@org.picocontainer.annotations.Nullable ProjectPullRequestsLoader loader, ScannerProperties scannerProperties) { - if (pullRequests != null) { - return pullRequests; - } - + @Bean("ProjectPullRequests") + public ProjectPullRequests provide(@Nullable ProjectPullRequestsLoader loader, ScannerProperties scannerProperties) { if (loader == null) { - pullRequests = new ProjectPullRequests(Collections.emptyList()); - return pullRequests; + return new ProjectPullRequests(Collections.emptyList()); } Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - pullRequests = loader.load(scannerProperties.getProjectKey()); + ProjectPullRequests pullRequests = loader.load(scannerProperties.getProjectKey()); profiler.stopInfo(); return pullRequests; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java index d949f49ad7e..65e321006a4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java @@ -22,8 +22,13 @@ package org.sonar.scanner.scan.filesystem; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.predicates.DefaultFilePredicates; +import javax.annotation.Priority; +import javax.inject.Inject; + +@Priority(1) public class DefaultModuleFileSystem extends MutableFileSystem { + @Inject public DefaultModuleFileSystem(ModuleInputComponentStore moduleInputFileCache, DefaultInputModule module) { super(module.getBaseDir(), moduleInputFileCache, new DefaultFilePredicates(module.getBaseDir())); initFields(module); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java index 57946189e3f..1311ff59214 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java @@ -22,8 +22,13 @@ package org.sonar.scanner.scan.filesystem; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.predicates.DefaultFilePredicates; +import javax.annotation.Priority; +import javax.inject.Inject; + +@Priority(2) public class DefaultProjectFileSystem extends MutableFileSystem { + @Inject public DefaultProjectFileSystem(InputComponentStore inputComponentStore, DefaultInputProject project) { super(project.getBaseDir(), inputComponentStore, new DefaultFilePredicates(project.getBaseDir())); setFields(project); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 96b0974c98e..7ea8799c855 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -90,14 +90,6 @@ public class FileIndexer { this.projectExclusionFilters = projectExclusionFilters; } - public FileIndexer(DefaultInputProject project, ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore, - ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, - IssueExclusionsLoader issueExclusionsLoader, MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, - LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties) { - this(project, scannerComponentIdGenerator, componentStore, projectExclusionFilters, projectCoverageAndDuplicationExclusions, issueExclusionsLoader, - metadataGenerator, sensorStrategy, languageDetection, analysisWarnings, properties, new InputFileFilter[0]); - } - void indexFile(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, Path sourceFile, Type type, ProgressReport progressReport, ProjectFileIndexer.ExclusionCounter exclusionCounter, @Nullable IgnoreCommand ignoreCommand) throws IOException { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java index 071864ac29b..1a7acc61189 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java @@ -22,29 +22,25 @@ package org.sonar.scanner.scm; import java.nio.file.Path; import java.util.Collection; import javax.annotation.CheckForNull; -import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.api.impl.utils.ScannerUtils; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.scan.branch.BranchConfiguration; -import org.sonar.api.impl.utils.ScannerUtils; +import org.springframework.context.annotation.Bean; -public class ScmChangedFilesProvider extends ProviderAdapter { +public class ScmChangedFilesProvider { private static final Logger LOG = Loggers.get(ScmChangedFilesProvider.class); private static final String LOG_MSG = "SCM collecting changed files in the branch"; - private ScmChangedFiles scmBranchChangedFiles; - + @Bean("ScmChangedFiles") public ScmChangedFiles provide(ScmConfiguration scmConfiguration, BranchConfiguration branchConfiguration, DefaultInputProject project) { - if (scmBranchChangedFiles == null) { Path rootBaseDir = project.getBaseDir(); Collection<Path> changedFiles = loadChangedFilesIfNeeded(scmConfiguration, branchConfiguration, rootBaseDir); validatePaths(changedFiles); - scmBranchChangedFiles = new ScmChangedFiles(changedFiles); - } - return scmBranchChangedFiles; + return new ScmChangedFiles(changedFiles); } private static void validatePaths(@javax.annotation.Nullable Collection<Path> paths) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java index 05be6c2595a..25d91d49d31 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java @@ -24,11 +24,11 @@ import java.util.Map; import java.util.stream.Collectors; import javax.annotation.CheckForNull; import org.apache.commons.lang.StringUtils; -import org.picocontainer.Startable; import org.sonar.api.CoreProperties; import org.sonar.api.Properties; import org.sonar.api.Property; import org.sonar.api.PropertyType; +import org.sonar.api.Startable; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.config.Configuration; import org.sonar.api.notifications.AnalysisWarnings; @@ -67,7 +67,8 @@ public class ScmConfiguration implements Startable { private ScmProvider provider; - public ScmConfiguration(InputModuleHierarchy moduleHierarchy, Configuration settings, AnalysisWarnings analysisWarnings, ScmProvider... providers) { + public ScmConfiguration(InputModuleHierarchy moduleHierarchy, Configuration settings, AnalysisWarnings analysisWarnings, + ScmProvider... providers) { this.moduleHierarchy = moduleHierarchy; this.settings = settings; this.analysisWarnings = analysisWarnings; @@ -76,10 +77,6 @@ public class ScmConfiguration implements Startable { } } - public ScmConfiguration(InputModuleHierarchy moduleHierarchy, Configuration settings, AnalysisWarnings analysisWarnings) { - this(moduleHierarchy, settings, analysisWarnings, new ScmProvider[0]); - } - @Override public void start() { if (isDisabled()) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java index 4874b528357..a33a00961f4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java @@ -34,9 +34,9 @@ public class ModuleSensorContext extends ProjectSensorContext { private final InputModule module; - public ModuleSensorContext(DefaultInputProject project, InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, + public ModuleSensorContext(DefaultInputProject project, InputModule module, Configuration config, Settings mutableModuleSettings, FileSystem fs, ActiveRules activeRules, SensorStorage sensorStorage, SonarRuntime sonarRuntime) { - super(project, config, mutableSettings, fs, activeRules, sensorStorage, sonarRuntime); + super(project, config, mutableModuleSettings, fs, activeRules, sensorStorage, sonarRuntime); this.module = module; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java index 34366b17d9e..d723bb2ebf3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java @@ -24,6 +24,7 @@ import java.util.stream.Collectors; import org.sonar.api.batch.sensor.Sensor; import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.bootstrap.AbstractExtensionDictionary; +import org.sonar.scanner.bootstrap.SpringComponentContainer; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.MutableFileSystem; @@ -34,7 +35,7 @@ public class ModuleSensorExtensionDictionary extends AbstractExtensionDictionary private final MutableFileSystem fileSystem; private final BranchConfiguration branchConfiguration; - public ModuleSensorExtensionDictionary(ComponentContainer componentContainer, ModuleSensorContext sensorContext, ModuleSensorOptimizer sensorOptimizer, + public ModuleSensorExtensionDictionary(SpringComponentContainer componentContainer, ModuleSensorContext sensorContext, ModuleSensorOptimizer sensorOptimizer, MutableFileSystem fileSystem, BranchConfiguration branchConfiguration) { super(componentContainer); this.sensorContext = sensorContext; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java index 2352db54cba..60b31745d19 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java @@ -23,8 +23,8 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import org.sonar.api.scanner.sensor.ProjectSensor; -import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.bootstrap.AbstractExtensionDictionary; +import org.sonar.scanner.bootstrap.SpringComponentContainer; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.MutableFileSystem; @@ -35,7 +35,7 @@ public class ProjectSensorExtensionDictionary extends AbstractExtensionDictionar private final MutableFileSystem fileSystem; private final BranchConfiguration branchConfiguration; - public ProjectSensorExtensionDictionary(ComponentContainer componentContainer, ProjectSensorContext sensorContext, ProjectSensorOptimizer sensorOptimizer, + public ProjectSensorExtensionDictionary(SpringComponentContainer componentContainer, ProjectSensorContext sensorContext, ProjectSensorOptimizer sensorOptimizer, MutableFileSystem fileSystem, BranchConfiguration branchConfiguration) { super(componentContainer); this.sensorContext = sensorContext; |