@@ -72,7 +72,10 @@ public class ServerPluginRepository implements PluginRepository, Startable { | |||
private static final Logger LOG = Loggers.get(ServerPluginRepository.class); | |||
private static final String[] JAR_FILE_EXTENSIONS = new String[] {"jar"}; | |||
// List of plugins that are silently removed if installed | |||
private static final Set<String> DEFAULT_BLACKLISTED_PLUGINS = ImmutableSet.of("scmactivity", "issuesreport"); | |||
// List of plugins that should prevent the server to finish its startup | |||
private static final Set<String> FORBIDDEN_COMPATIBLE_PLUGINS = ImmutableSet.of("sqale", "report", "views"); | |||
private static final Joiner SLASH_JOINER = Joiner.on(" / ").skipNulls(); | |||
private final Server server; | |||
@@ -157,15 +160,19 @@ public class ServerPluginRepository implements PluginRepository, Startable { | |||
} | |||
private void registerPluginInfo(PluginInfo info) { | |||
if (blacklistedPluginKeys.contains(info.getKey())) { | |||
LOG.warn("Plugin {} [{}] is blacklisted and is being uninstalled.", info.getName(), info.getKey()); | |||
String pluginKey = info.getKey(); | |||
if (blacklistedPluginKeys.contains(pluginKey)) { | |||
LOG.warn("Plugin {} [{}] is blacklisted and is being uninstalled.", info.getName(), pluginKey); | |||
org.sonar.core.util.FileUtils.deleteQuietly(info.getNonNullJarFile()); | |||
return; | |||
} | |||
PluginInfo existing = pluginInfosByKeys.put(info.getKey(), info); | |||
if (FORBIDDEN_COMPATIBLE_PLUGINS.contains(pluginKey)) { | |||
throw MessageException.of(String.format("Plugin '%s' is no more compatible with this version of SonarQube", pluginKey)); | |||
} | |||
PluginInfo existing = pluginInfosByKeys.put(pluginKey, info); | |||
if (existing != null) { | |||
throw MessageException.of(format("Found two files for the same plugin [%s]: %s and %s", | |||
info.getKey(), info.getNonNullJarFile().getName(), existing.getNonNullJarFile().getName())); | |||
pluginKey, info.getNonNullJarFile().getName(), existing.getNonNullJarFile().getName())); | |||
} | |||
} |
@@ -30,6 +30,7 @@ import org.junit.After; | |||
import org.junit.Before; | |||
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.platform.Server; | |||
@@ -48,6 +49,9 @@ import static org.mockito.Mockito.when; | |||
public class ServerPluginRepositoryTest { | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@@ -309,6 +313,33 @@ public class ServerPluginRepositoryTest { | |||
assertThat(logs.logs()).contains("Plugin Foo [foo] is ignored because entry point class is not defined"); | |||
} | |||
@Test | |||
public void fail_when_views_is_installed() throws Exception { | |||
copyTestPluginTo("fake-views-plugin", fs.getInstalledPluginsDir()); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("Plugin 'views' is no more compatible with this version of SonarQube"); | |||
underTest.start(); | |||
} | |||
@Test | |||
public void fail_when_sqale_plugin_is_installed() throws Exception { | |||
copyTestPluginTo("fake-sqale-plugin", fs.getInstalledPluginsDir()); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("Plugin 'sqale' is no more compatible with this version of SonarQube"); | |||
underTest.start(); | |||
} | |||
@Test | |||
public void fail_when_report_is_installed() throws Exception { | |||
copyTestPluginTo("fake-report-plugin", fs.getInstalledPluginsDir()); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("Plugin 'report' is no more compatible with this version of SonarQube"); | |||
underTest.start(); | |||
} | |||
/** | |||
* Some plugins can only extend the classloader of base plugin, without declaring new extensions. | |||
*/ |
@@ -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>fake-report-plugin</artifactId> | |||
<version>0.1-SNAPSHOT</version> | |||
<packaging>sonar-plugin</packaging> | |||
<name>Fake Report Plugin</name> | |||
<description>Fake Report Plugin</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>report</pluginKey> | |||
<pluginClass>BasePlugin</pluginClass> | |||
</configuration> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,11 @@ | |||
import org.sonar.api.SonarPlugin; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public class BasePlugin extends SonarPlugin { | |||
public List getExtensions() { | |||
return Collections.emptyList(); | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
package org.sonar.plugins.testbase.api; | |||
public class BaseApi { | |||
public void doNothing() { | |||
} | |||
} |
@@ -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>fake-sqale-plugin</artifactId> | |||
<version>0.1-SNAPSHOT</version> | |||
<packaging>sonar-plugin</packaging> | |||
<name>Fake SQALE Plugin</name> | |||
<description>Fake SQALE Plugin</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>sqale</pluginKey> | |||
<pluginClass>BasePlugin</pluginClass> | |||
</configuration> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,11 @@ | |||
import org.sonar.api.SonarPlugin; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public class BasePlugin extends SonarPlugin { | |||
public List getExtensions() { | |||
return Collections.emptyList(); | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
package org.sonar.plugins.testbase.api; | |||
public class BaseApi { | |||
public void doNothing() { | |||
} | |||
} |
@@ -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>fake-views-plugin</artifactId> | |||
<version>0.1-SNAPSHOT</version> | |||
<packaging>sonar-plugin</packaging> | |||
<name>Fake Views Plugin</name> | |||
<description>Fake Views Plugin</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>views</pluginKey> | |||
<pluginClass>BasePlugin</pluginClass> | |||
</configuration> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,31 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import org.sonar.api.SonarPlugin; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public class BasePlugin extends SonarPlugin { | |||
public List getExtensions() { | |||
return Collections.emptyList(); | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
package org.sonar.plugins.testbase.api; | |||
public class BaseApi { | |||
public void doNothing() { | |||
} | |||
} |
@@ -14,6 +14,9 @@ | |||
<module>test-libs-plugin</module> | |||
<module>test-require-plugin</module> | |||
<module>test-requirenew-plugin</module> | |||
<module>fake-report-plugin</module> | |||
<module>fake-sqale-plugin</module> | |||
<module>fake-views-plugin</module> | |||
</modules> | |||
</project> |