diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-03-23 14:35:41 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-03-24 14:54:02 +0100 |
commit | 067f651cd32f86f543296262729bd6db665e1f24 (patch) | |
tree | a39e4522582832b5a142b41eccf168999f45cf04 /server/sonar-ce | |
parent | 0d6edb21c09e328980a272dd21a37befa49be92a (diff) | |
download | sonarqube-067f651cd32f86f543296262729bd6db665e1f24.tar.gz sonarqube-067f651cd32f86f543296262729bd6db665e1f24.zip |
SONAR-6731 Fix loading of plugins by CE when running on MS Windows
Diffstat (limited to 'server/sonar-ce')
14 files changed, 581 insertions, 4 deletions
diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginJarExploder.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginJarExploder.java new file mode 100644 index 00000000000..a9d64dd3c37 --- /dev/null +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginJarExploder.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.ce.container; + +import java.io.File; +import org.apache.commons.io.FileUtils; +import org.sonar.api.platform.ServerFileSystem; +import org.sonar.api.utils.ZipUtils; +import org.sonar.core.platform.ExplodedPlugin; +import org.sonar.core.platform.PluginInfo; +import org.sonar.core.platform.PluginJarExploder; + +/** + * Explodes the plugin JARs of extensions/plugins/ into a temporary directory + * dedicated to compute engine. + */ +public class CePluginJarExploder extends PluginJarExploder { + + private static final String TEMP_RELATIVE_PATH = "ce-exploded-plugins"; + private final ServerFileSystem fs; + + public CePluginJarExploder(ServerFileSystem fs) { + this.fs = fs; + } + + @Override + public ExplodedPlugin explode(PluginInfo pluginInfo) { + File tempDir = new File(fs.getTempDir(), TEMP_RELATIVE_PATH); + File toDir = new File(tempDir, pluginInfo.getKey()); + try { + org.sonar.core.util.FileUtils.cleanDirectory(toDir); + + File jarSource = pluginInfo.getNonNullJarFile(); + File jarTarget = new File(toDir, jarSource.getName()); + FileUtils.copyFile(jarSource, jarTarget); + ZipUtils.unzip(jarSource, toDir, newLibFilter()); + return explodeFromUnzippedDir(pluginInfo.getKey(), jarTarget, toDir); + } catch (Exception e) { + throw new IllegalStateException(String.format( + "Fail to unzip plugin [%s] %s to %s", pluginInfo.getKey(), pluginInfo.getNonNullJarFile().getAbsolutePath(), toDir.getAbsolutePath()), e); + } + } +} diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginRepository.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginRepository.java new file mode 100644 index 00000000000..0f24f3d6b1d --- /dev/null +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/CePluginRepository.java @@ -0,0 +1,120 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.ce.container; + +import com.google.common.collect.ImmutableList; +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.commons.io.FileUtils; +import org.picocontainer.Startable; +import org.sonar.api.Plugin; +import org.sonar.api.utils.log.Loggers; +import org.sonar.core.platform.PluginInfo; +import org.sonar.core.platform.PluginLoader; +import org.sonar.core.platform.PluginRepository; +import org.sonar.server.platform.DefaultServerFileSystem; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; + +/** + * Entry point to load plugins on startup. It assumes that plugins + * have been correctly installed/uninstalled/updated during web server startup + */ +public class CePluginRepository implements PluginRepository, Startable { + + private static final String[] JAR_FILE_EXTENSIONS = new String[] {"jar"}; + private static final String NOT_STARTED_YET = "not started yet"; + + private final DefaultServerFileSystem fs; + private final PluginLoader loader; + private final AtomicBoolean started = new AtomicBoolean(false); + + // following fields are available after startup + private final Map<String, PluginInfo> pluginInfosByKeys = new HashMap<>(); + private final Map<String, Plugin> pluginInstancesByKeys = new HashMap<>(); + + public CePluginRepository(DefaultServerFileSystem fs, PluginLoader loader) { + this.fs = fs; + this.loader = loader; + } + + @Override + public void start() { + Loggers.get(getClass()).info("Load plugins"); + for (File file : listJarFiles(fs.getInstalledPluginsDir())) { + PluginInfo info = PluginInfo.create(file); + pluginInfosByKeys.put(info.getKey(), info); + } + pluginInstancesByKeys.putAll(loader.load(pluginInfosByKeys)); + started.set(true); + } + + @Override + public void stop() { + // close classloaders + loader.unload(pluginInstancesByKeys.values()); + pluginInstancesByKeys.clear(); + pluginInfosByKeys.clear(); + started.set(false); + } + + @Override + public Collection<PluginInfo> getPluginInfos() { + checkState(started.get(), NOT_STARTED_YET); + return ImmutableList.copyOf(pluginInfosByKeys.values()); + } + + @Override + public PluginInfo getPluginInfo(String key) { + checkState(started.get(), NOT_STARTED_YET); + PluginInfo info = pluginInfosByKeys.get(key); + if (info == null) { + throw new IllegalArgumentException(format("Plugin [%s] does not exist", key)); + } + return info; + } + + @Override + public Plugin getPluginInstance(String key) { + checkState(started.get(), NOT_STARTED_YET); + Plugin plugin = pluginInstancesByKeys.get(key); + checkArgument(plugin != null, "Plugin [%s] does not exist", key); + return plugin; + } + + @Override + public boolean hasPlugin(String key) { + checkState(started.get(), NOT_STARTED_YET); + return pluginInfosByKeys.containsKey(key); + } + + private static Collection<File> listJarFiles(File dir) { + if (dir.exists()) { + return FileUtils.listFiles(dir, JAR_FILE_EXTENSIONS, false); + } + return Collections.emptyList(); + } +} diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 7354d63978c..42527bf4e8b 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -110,8 +110,6 @@ import org.sonar.server.platform.ServerLogging; import org.sonar.server.platform.TempFolderProvider; import org.sonar.server.plugins.InstalledPluginReferentialFactory; import org.sonar.server.plugins.ServerExtensionInstaller; -import org.sonar.server.plugins.ServerPluginJarExploder; -import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.properties.ProjectSettingsFactory; import org.sonar.server.qualityprofile.BuiltInProfiles; import org.sonar.server.qualityprofile.QProfileComparison; @@ -187,9 +185,9 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { // plugins PluginClassloaderFactory.class, - ServerPluginJarExploder.class, + CePluginJarExploder.class, PluginLoader.class, - ServerPluginRepository.class, + CePluginRepository.class, InstalledPluginReferentialFactory.class, ServerExtensionInstaller.class, diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java new file mode 100644 index 00000000000..ae7dcac8378 --- /dev/null +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java @@ -0,0 +1,123 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.ce.container; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.platform.ServerFileSystem; +import org.sonar.core.platform.ExplodedPlugin; +import org.sonar.core.platform.PluginInfo; + +import static org.apache.commons.io.FileUtils.sizeOfDirectory; +import static org.assertj.core.api.Assertions.assertThat; + +public class CePluginJarExploderTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + DumbFileSystem fs = new DumbFileSystem(temp); + CePluginJarExploder underTest = new CePluginJarExploder(fs); + + @Test + public void explode_jar_to_temp_directory() throws Exception { + PluginInfo info = PluginInfo.create(plugin1Jar()); + + ExplodedPlugin exploded = underTest.explode(info); + + // all the files loaded by classloaders (JAR + META-INF/libs/*.jar) are copied to a dedicated temp directory + File copiedJar = exploded.getMain(); + + assertThat(exploded.getKey()).isEqualTo("test"); + assertThat(copiedJar).isFile().exists(); + assertThat(copiedJar.getParentFile()).isDirectory().hasName("test"); + assertThat(copiedJar.getParentFile().getParentFile()).isDirectory().hasName("ce-exploded-plugins"); + } + + @Test + public void plugins_do_not_overlap() throws Exception { + PluginInfo info1 = PluginInfo.create(plugin1Jar()); + PluginInfo info2 = PluginInfo.create(plugin2Jar()); + + ExplodedPlugin exploded1 = underTest.explode(info1); + ExplodedPlugin exploded2 = underTest.explode(info2); + + assertThat(exploded1.getKey()).isEqualTo("test"); + assertThat(exploded1.getMain()).isFile().exists().hasName("sonar-test-plugin-0.1-SNAPSHOT.jar"); + assertThat(exploded2.getKey()).isEqualTo("test2"); + assertThat(exploded2.getMain()).isFile().exists().hasName("sonar-test2-plugin-0.1-SNAPSHOT.jar"); + } + + @Test + public void explode_is_reentrant() throws Exception { + PluginInfo info = PluginInfo.create(plugin1Jar()); + + ExplodedPlugin exploded1 = underTest.explode(info); + long dirSize1 = sizeOfDirectory(exploded1.getMain().getParentFile()); + + ExplodedPlugin exploded2 = underTest.explode(info); + long dirSize2 = sizeOfDirectory(exploded2.getMain().getParentFile()); + assertThat(exploded2.getMain().getCanonicalPath()).isEqualTo(exploded1.getMain().getCanonicalPath()); + assertThat(dirSize1).isEqualTo(dirSize2); + } + + private File plugin1Jar() { + return new File("src/test/plugins/sonar-test-plugin/target/sonar-test-plugin-0.1-SNAPSHOT.jar"); + } + + private File plugin2Jar() { + return new File("src/test/plugins/sonar-test2-plugin/target/sonar-test2-plugin-0.1-SNAPSHOT.jar"); + } + + private class DumbFileSystem implements ServerFileSystem { + private final TemporaryFolder temp; + private File tempDir; + + public DumbFileSystem(TemporaryFolder temp) { + this.temp = temp; + } + + @Override + public File getHomeDir() { + throw new UnsupportedOperationException(); + } + + @Override + public File getTempDir() { + if (tempDir == null) { + try { + this.tempDir = temp.newFolder(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + return tempDir; + } + + @Override + public List<File> getExtensions(String dirName, String... suffixes) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginRepositoryTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginRepositoryTest.java new file mode 100644 index 00000000000..a7ebbc8eff3 --- /dev/null +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginRepositoryTest.java @@ -0,0 +1,159 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.ce.container; + +import com.google.common.collect.Maps; +import java.io.File; +import java.util.Collection; +import java.util.Map; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import org.sonar.api.Plugin; +import org.sonar.core.platform.PluginInfo; +import org.sonar.core.platform.PluginLoader; +import org.sonar.server.platform.DefaultServerFileSystem; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CePluginRepositoryTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + DefaultServerFileSystem fs = mock(DefaultServerFileSystem.class, Mockito.RETURNS_DEEP_STUBS); + PluginLoader pluginLoader = new DumbPluginLoader(); + CePluginRepository underTest = new CePluginRepository(fs, pluginLoader); + + @After + public void tearDown() { + underTest.stop(); + } + + @Test + public void empty_plugins() throws Exception { + // empty folder + when(fs.getInstalledPluginsDir()).thenReturn(temp.newFolder()); + + underTest.start(); + + assertThat(underTest.getPluginInfos()).isEmpty(); + assertThat(underTest.hasPlugin("foo")).isFalse(); + } + + @Test + public void load_plugins() throws Exception { + String pluginKey = "test"; + when(fs.getInstalledPluginsDir()).thenReturn(new File("src/test/plugins/sonar-test-plugin/target")); + + underTest.start(); + + assertThat(underTest.getPluginInfos()).extracting("key").containsOnly(pluginKey); + assertThat(underTest.getPluginInfo(pluginKey).getKey()).isEqualTo(pluginKey); + assertThat(underTest.getPluginInstance(pluginKey)).isNotNull(); + assertThat(underTest.hasPlugin(pluginKey)).isTrue(); + } + + @Test + public void getPluginInfo_fails_if_plugin_does_not_exist() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Plugin [foo] does not exist"); + + // empty folder + when(fs.getInstalledPluginsDir()).thenReturn(temp.newFolder()); + underTest.start(); + underTest.getPluginInfo("foo"); + } + + @Test + public void getPluginInstance_fails_if_plugin_does_not_exist() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Plugin [foo] does not exist"); + + // empty folder + when(fs.getInstalledPluginsDir()).thenReturn(temp.newFolder()); + underTest.start(); + underTest.getPluginInstance("foo"); + } + + @Test + public void getPluginInstance_throws_ISE_if_repo_is_not_started() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("not started yet"); + + underTest.getPluginInstance("foo"); + } + + @Test + public void getPluginInfo_throws_ISE_if_repo_is_not_started() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("not started yet"); + + underTest.getPluginInfo("foo"); + } + + @Test + public void hasPlugin_throws_ISE_if_repo_is_not_started() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("not started yet"); + + underTest.hasPlugin("foo"); + } + + @Test + public void getPluginInfos_throws_ISE_if_repo_is_not_started() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("not started yet"); + + underTest.getPluginInfos(); + } + + private static class DumbPluginLoader extends PluginLoader { + + public DumbPluginLoader() { + super(null, null); + } + + /** + * Does nothing except returning the specified list of plugins + */ + @Override + public Map<String, Plugin> load(Map<String, PluginInfo> infoByKeys) { + Map<String, Plugin> result = Maps.newHashMap(); + for (String pluginKey : infoByKeys.keySet()) { + result.put(pluginKey, mock(Plugin.class)); + } + return result; + } + + @Override + public void unload(Collection<Plugin> plugins) { + + } + } +} diff --git a/server/sonar-ce/src/test/plugins/.gitignore b/server/sonar-ce/src/test/plugins/.gitignore new file mode 100644 index 00000000000..a945b8525e6 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/.gitignore @@ -0,0 +1,7 @@ +# see README.txt +!*/target/ +*/target/classes/ +*/target/maven-archiver/ +*/target/maven-status/ +*/target/test-*/ + diff --git a/server/sonar-ce/src/test/plugins/README.txt b/server/sonar-ce/src/test/plugins/README.txt new file mode 100644 index 00000000000..c53a66d52f2 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/README.txt @@ -0,0 +1,3 @@ +This directory provides the fake plugins used by tests. These tests are rarely changed, so generated +artifacts are stored in Git repository (see .gitignore). It avoids from adding unnecessary modules +to build. diff --git a/server/sonar-ce/src/test/plugins/pom.xml b/server/sonar-ce/src/test/plugins/pom.xml new file mode 100644 index 00000000000..328eff0f237 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/pom.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.sonarsource.sonarqube.tests</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <modules> + <module>test-base-plugin</module> + </modules> + +</project> diff --git a/server/sonar-ce/src/test/plugins/sonar-test-plugin/pom.xml b/server/sonar-ce/src/test/plugins/sonar-test-plugin/pom.xml new file mode 100644 index 00000000000..d2efd359b4a --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test-plugin/pom.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.sonarsource.sonarqube.tests</groupId> + <artifactId>sonar-test-plugin</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>sonar-plugin</packaging> + <name>Test Plugin</name> + <description>Simple standalone plugin. Used by other fake plugins.</description> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>4.5.4</version> + <scope>provided</scope> + </dependency> + </dependencies> + <build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> + <artifactId>sonar-packaging-maven-plugin</artifactId> + <version>1.15</version> + <extensions>true</extensions> + <configuration> + <pluginKey>test</pluginKey> + <pluginClass>TestPlugin</pluginClass> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/server/sonar-ce/src/test/plugins/sonar-test-plugin/src/TestPlugin.java b/server/sonar-ce/src/test/plugins/sonar-test-plugin/src/TestPlugin.java new file mode 100644 index 00000000000..a1f4376adc8 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test-plugin/src/TestPlugin.java @@ -0,0 +1,11 @@ +import org.sonar.api.SonarPlugin; + +import java.util.Collections; +import java.util.List; + +public class TestPlugin extends SonarPlugin { + + public List getExtensions() { + return Collections.emptyList(); + } +} diff --git a/server/sonar-ce/src/test/plugins/sonar-test-plugin/target/sonar-test-plugin-0.1-SNAPSHOT.jar b/server/sonar-ce/src/test/plugins/sonar-test-plugin/target/sonar-test-plugin-0.1-SNAPSHOT.jar Binary files differnew file mode 100644 index 00000000000..cc9bbd8f7bf --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test-plugin/target/sonar-test-plugin-0.1-SNAPSHOT.jar diff --git a/server/sonar-ce/src/test/plugins/sonar-test2-plugin/pom.xml b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/pom.xml new file mode 100644 index 00000000000..fc4ecfa8e27 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/pom.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.sonarsource.sonarqube.tests</groupId> + <artifactId>sonar-test2-plugin</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>sonar-plugin</packaging> + <name>Test Plugin</name> + <description>Simple standalone plugin. Used by other fake plugins.</description> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>4.5.4</version> + <scope>provided</scope> + </dependency> + </dependencies> + <build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> + <artifactId>sonar-packaging-maven-plugin</artifactId> + <version>1.15</version> + <extensions>true</extensions> + <configuration> + <pluginKey>test2</pluginKey> + <pluginClass>Test2Plugin</pluginClass> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/server/sonar-ce/src/test/plugins/sonar-test2-plugin/src/Test2Plugin.java b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/src/Test2Plugin.java new file mode 100644 index 00000000000..3c790702b07 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/src/Test2Plugin.java @@ -0,0 +1,11 @@ +import org.sonar.api.SonarPlugin; + +import java.util.Collections; +import java.util.List; + +public class Test2Plugin extends SonarPlugin { + + public List getExtensions() { + return Collections.emptyList(); + } +} diff --git a/server/sonar-ce/src/test/plugins/sonar-test2-plugin/target/sonar-test2-plugin-0.1-SNAPSHOT.jar b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/target/sonar-test2-plugin-0.1-SNAPSHOT.jar Binary files differnew file mode 100644 index 00000000000..c205080f968 --- /dev/null +++ b/server/sonar-ce/src/test/plugins/sonar-test2-plugin/target/sonar-test2-plugin-0.1-SNAPSHOT.jar |