Fix loading of core plugins on Windows
[2020-06-07T13:26:26.841+0300] [plugin-manager-preloader] ERROR com.googlesource.gerrit.plugins.manager.repository.CorePluginsRepository : Invalid plugin filename
java.net.URISyntaxException: Illegal character in opaque part at index 11: Jar:file:c:\Projects\gerrit\bin\gerrit.war!/WEB-INF/plugins/gitiles.jar
at java.base/java.net.URI$Parser.fail(URI.java:2915)
at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
at java.base/java.net.URI$Parser.parse(URI.java:3122)
at java.base/java.net.URI.<init>(URI.java:600)
at com.googlesource.gerrit.plugins.manager.repository.CorePluginsRepository.extractPluginInfoFromJarEntry(CorePluginsRepository.java:59)
Bug: Issue 12885
Change-Id: Icade084c2c156ca3caa1bffd9ae6dcde61a43c3e
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java
index 55b4639..9ff15fb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java
@@ -16,8 +16,8 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Comparator.comparing;
-import static java.util.Objects.requireNonNull;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
@@ -41,21 +41,30 @@
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final String GERRIT_VERSION = Version.getVersion();
- private final SitePaths site;
private final CorePluginsDescriptions pluginsDescriptions;
+ private final String gerritWarUri;
+ private final Path siteGerritWar;
+ private static final char WINDOWS_FILE_SEPARATOR = '\\';
+ private static final char UNIX_FILE_SEPARATOR = '/';
@Inject
public CorePluginsRepository(SitePaths site, CorePluginsDescriptions pd) {
- this.site = site;
+ this(site.gerrit_war, site.gerrit_war.toString(), pd);
+ }
+
+ @VisibleForTesting
+ public CorePluginsRepository(Path siteGerritWar, String gerritWar, CorePluginsDescriptions pd) {
this.pluginsDescriptions = pd;
+ final String normalizedWar = gerritWar.replace(WINDOWS_FILE_SEPARATOR, UNIX_FILE_SEPARATOR);
+ this.gerritWarUri = Paths.get(normalizedWar).toUri().toString();
+ this.siteGerritWar = siteGerritWar;
}
@Nullable
private PluginInfo extractPluginInfoFromJarEntry(JarEntry entry) {
try {
Path entryName = Paths.get(entry.getName());
- URI pluginUrl =
- new URI("jar:file:" + requireNonNull(site.gerrit_war) + "!/" + entry.getName());
+ URI pluginUrl = new URI("jar:" + gerritWarUri + "!/" + entry.getName());
try (JarInputStream pluginJar = new JarInputStream(pluginUrl.toURL().openStream())) {
return getManifestEntry(pluginJar)
.map(
@@ -114,12 +123,12 @@
return ImmutableList.of();
}
- if (site.gerrit_war == null) {
+ if (siteGerritWar == null) {
logger.atWarning().log("Core plugins not available in non-war Gerrit distributions");
return ImmutableList.of();
}
- try (JarFile gerritWar = new JarFile(site.gerrit_war.toFile())) {
+ try (JarFile gerritWar = new JarFile(siteGerritWar.toFile())) {
return gerritWar.stream()
.filter(e -> e.getName().startsWith("WEB-INF/plugins") && e.getName().endsWith(".jar"))
.map(this::extractPluginInfoFromJarEntry)
diff --git a/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java b/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java
index d01d287..bd74235 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java
@@ -46,14 +46,9 @@
@Test
public void corePluginsRepositoryShouldReturnCorePluginsFromReleaseWar() throws IOException {
- SitePaths site = new SitePaths(random());
- PluginsRepository pluginRepo = new CorePluginsRepository(site, new CorePluginsDescriptions());
+ SitePaths site = prepareSiteDirWithReleaseWar();
- Path pathToReleaseWar =
- Paths.get(getenv("TEST_SRCDIR"), getenv("TEST_WORKSPACE"), "release.war");
- assume().that(pathToReleaseWar.toFile().exists()).isTrue();
- Files.createDirectories(site.bin_dir);
- Files.createSymbolicLink(site.gerrit_war, pathToReleaseWar);
+ PluginsRepository pluginRepo = new CorePluginsRepository(site, new CorePluginsDescriptions());
Collection<PluginInfo> plugins = pluginRepo.list(Version.getVersion());
assertThat(plugins.stream().map(p -> p.name).sorted().collect(toList()))
@@ -61,6 +56,30 @@
.inOrder();
}
+ @Test
+ public void corePluginsListFromReleaseWarShouldNotBeEmptyOnWindows() throws IOException {
+ char windowsSeparator = '\\';
+ SitePaths site = prepareSiteDirWithReleaseWar();
+
+ PluginsRepository pluginRepo =
+ new CorePluginsRepository(
+ site.gerrit_war,
+ site.gerrit_war.toString().replace('/', windowsSeparator),
+ new CorePluginsDescriptions());
+
+ assertThat(pluginRepo.list(Version.getVersion())).isNotEmpty();
+ }
+
+ private SitePaths prepareSiteDirWithReleaseWar() throws IOException {
+ SitePaths site = new SitePaths(random());
+ Path pathToReleaseWar =
+ Paths.get(getenv("TEST_SRCDIR"), getenv("TEST_WORKSPACE"), "release.war");
+ assume().that(pathToReleaseWar.toFile().exists()).isTrue();
+ Files.createDirectories(site.bin_dir);
+ Files.createSymbolicLink(site.gerrit_war, pathToReleaseWar);
+ return site;
+ }
+
private static String getenv(String name) {
String value = System.getenv(name);
assume().that(value).isNotNull();