Select injector during libModule loading

LibModules can override different part of Gerrit at startup, however
they need to specify which injector they are targeting.
Failing to target the correct injector would result in issues where
a just-in-time binding has been already resolved and thus it is not
possible anymore to override the binding.

Bug: Issue 10768
Change-Id: Ifebb7fd33ad74b534a75782d096db48c387a4c03
This commit is contained in:
Luca Milanesio
2019-04-29 07:26:11 +01:00
parent c65de11755
commit b8ec7e243f
6 changed files with 69 additions and 7 deletions

View File

@@ -1955,10 +1955,20 @@ By default unset, as the HTTP daemon must be configured externally
by the system administrator, and might not even be running on the
same host as Gerrit.
[[gerrit.installDbModule]]gerrit.installDbModule::
+
Repeatable list of class name of additional Guice modules to load at
Gerrit startup as part of the dbInjector and during the init phases.
Classes are resolved using the primary Gerrit class loader, hence the
class needs to be either declared in Gerrit or an additional JAR
located under the `/lib` directory.
+
By default unset.
[[gerrit.installModule]]gerrit.installModule::
+
Repeatable list of class name of additional Guice modules to load at
Gerrit startup and init phases.
Gerrit startup as part of the sysInjector and during the init phases.
Classes are resolved using the primary Gerrit class loader, hence the
class needs to be either declared in Gerrit or an additional JAR
located under the `/lib` directory.
@@ -1970,6 +1980,7 @@ Example:
[gerrit]
installModule = com.googlesource.gerrit.libmodule.MyModule
installModule = com.example.abc.OurSpecialSauceModule
installDbModule = com.example.def.OurCustomProvider
----
[[gerrit.listProjectsFromIndex]]gerrit.listProjectsFromIndex::

View File

@@ -41,6 +41,7 @@ import com.google.gerrit.lucene.LuceneIndexModule;
import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
import com.google.gerrit.pgm.util.LogFileCompressor;
import com.google.gerrit.server.LibModuleLoader;
import com.google.gerrit.server.LibModuleType;
import com.google.gerrit.server.ModuleOverloader;
import com.google.gerrit.server.StartupChecks;
import com.google.gerrit.server.account.AccountDeactivator;
@@ -263,7 +264,8 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi
modules.add(new GerritServerConfigModule());
}
modules.add(new DropWizardMetricMaker.ApiModule());
return Guice.createInjector(PRODUCTION, modules);
return Guice.createInjector(
PRODUCTION, LibModuleLoader.loadModules(cfgInjector, LibModuleType.DB_MODULE));
}
private Injector createCfgInjector() {
@@ -336,7 +338,8 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi
modules.add(new AccountDeactivator.Module());
modules.add(new DefaultProjectNameLockManager.Module());
return cfgInjector.createChildInjector(
ModuleOverloader.override(modules, LibModuleLoader.loadModules(cfgInjector)));
ModuleOverloader.override(
modules, LibModuleLoader.loadModules(cfgInjector, LibModuleType.SYS_MODULE)));
}
private Module createIndexModule() {

View File

@@ -51,6 +51,7 @@ import com.google.gerrit.pgm.util.LogFileCompressor;
import com.google.gerrit.pgm.util.RuntimeShutdown;
import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.server.LibModuleLoader;
import com.google.gerrit.server.LibModuleType;
import com.google.gerrit.server.ModuleOverloader;
import com.google.gerrit.server.StartupChecks;
import com.google.gerrit.server.account.AccountDeactivator;
@@ -476,7 +477,8 @@ public class Daemon extends SiteProgram {
modules.add(new LocalMergeSuperSetComputation.Module());
modules.add(new DefaultProjectNameLockManager.Module());
return cfgInjector.createChildInjector(
ModuleOverloader.override(modules, LibModuleLoader.loadModules(cfgInjector)));
ModuleOverloader.override(
modules, LibModuleLoader.loadModules(cfgInjector, LibModuleType.SYS_MODULE)));
}
private Module createIndexModule() {

View File

@@ -21,6 +21,9 @@ import com.google.gerrit.common.Die;
import com.google.gerrit.metrics.DisabledMetricMaker;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
import com.google.gerrit.server.LibModuleLoader;
import com.google.gerrit.server.LibModuleType;
import com.google.gerrit.server.ModuleOverloader;
import com.google.gerrit.server.config.GerritRuntime;
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
@@ -118,7 +121,10 @@ public abstract class SiteProgram extends AbstractProgram {
modules.add(cfgInjector.getInstance(GitRepositoryManagerModule.class));
try {
return Guice.createInjector(PRODUCTION, modules);
return Guice.createInjector(
PRODUCTION,
ModuleOverloader.override(
modules, LibModuleLoader.loadModules(cfgInjector, LibModuleType.DB_MODULE)));
} catch (CreationException ce) {
Message first = ce.getErrorMessages().iterator().next();
Throwable why = first.getCause();

View File

@@ -30,9 +30,9 @@ import org.eclipse.jgit.lib.Config;
public class LibModuleLoader {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static List<Module> loadModules(Injector parent) {
public static List<Module> loadModules(Injector parent, LibModuleType moduleType) {
Config cfg = getConfig(parent);
return Arrays.stream(cfg.getStringList("gerrit", null, "installModule"))
return Arrays.stream(cfg.getStringList("gerrit", null, "install" + moduleType.getConfigKey()))
.map(m -> createModule(parent, m))
.collect(toList());
}

View File

@@ -0,0 +1,40 @@
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server;
/** Loadable module type for the different Gerrit injectors. */
public enum LibModuleType {
/** Module for the sysInjector. */
SYS_MODULE("Module"),
/** Module for the dbInjector. */
DB_MODULE("DbModule");
private final String configKey;
LibModuleType(String configKey) {
this.configKey = configKey;
}
/**
* Returns the module type for libModule loaded from <gerrit_site/lib> directory.
*
* @return module type string
*/
public String getConfigKey() {
return configKey;
}
}