Support for loading Guice modules from /lib
Gerrit already has "pluggable" features that need to be installed at the early stages of the bootstrap phase and cannot be "unplugged" as plugins do. Attendees at the recent hackathon in Mountain View decided to call this new entities "LibModules", and configure them in the gerrit.config as follows: [gerrit] installModule = com.googlesource.gerrit.libmodule.MyModule installModule = com.example.abc.OurSpecialSauceModule Change-Id: Id8bf1a2e88b14c8e9125f20cb10a041d47799100
This commit is contained in:
parent
8e5418db0a
commit
62cc3503b9
@ -1997,6 +1997,23 @@ 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.installModule]]gerrit.installModule::
|
||||
+
|
||||
Repeatable list of class name of additional Guice modules to load at
|
||||
Gerrit startup and 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.
|
||||
+
|
||||
Example:
|
||||
----
|
||||
[gerrit]
|
||||
installModule = com.googlesource.gerrit.libmodule.MyModule
|
||||
installModule = com.example.abc.OurSpecialSauceModule
|
||||
----
|
||||
|
||||
[[gerrit.reportBugUrl]]gerrit.reportBugUrl::
|
||||
+
|
||||
URL to direct users to when they need to report a bug.
|
||||
|
@ -24,6 +24,7 @@ import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
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.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.config.GerritServerConfigModule;
|
||||
import com.google.gerrit.server.config.SitePath;
|
||||
@ -180,6 +181,7 @@ public abstract class SiteProgram extends AbstractProgram {
|
||||
modules.add(new SchemaModule());
|
||||
modules.add(cfgInjector.getInstance(GitRepositoryManagerModule.class));
|
||||
modules.add(new ConfigNotesMigration.Module());
|
||||
modules.addAll(LibModuleLoader.loadModules(cfgInjector));
|
||||
|
||||
try {
|
||||
return Guice.createInjector(PRODUCTION, modules);
|
||||
|
@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2016 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;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.ProvisionException;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** Loads configured Guice modules from {@code gerrit.installModule}. */
|
||||
public class LibModuleLoader {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(LibModuleLoader.class);
|
||||
|
||||
public static List<Module> loadModules(Injector parent) {
|
||||
Config cfg = getConfig(parent);
|
||||
return Arrays.stream(cfg.getStringList("gerrit", null, "installModule"))
|
||||
.map(m -> createModule(parent, m))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
private static Config getConfig(Injector i) {
|
||||
return i.getInstance(Key.get(Config.class, GerritServerConfig.class));
|
||||
}
|
||||
|
||||
private static Module createModule(Injector injector, String className) {
|
||||
Module m = injector.getInstance(loadModule(className));
|
||||
log.info("Installed module {}", className);
|
||||
return m;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Class<Module> loadModule(String className) {
|
||||
try {
|
||||
return (Class<Module>) Class.forName(className);
|
||||
} catch (ClassNotFoundException | LinkageError e) {
|
||||
String msg = "Cannot load LibModule " + className;
|
||||
log.error(msg, e);
|
||||
throw new ProvisionException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
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.account.InternalAccountDirectory;
|
||||
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
|
||||
import com.google.gerrit.server.change.ChangeCleanupRunner;
|
||||
@ -339,6 +340,7 @@ public class WebAppInitializer extends GuiceServletContextListener
|
||||
});
|
||||
modules.add(new GarbageCollectionModule());
|
||||
modules.add(new ChangeCleanupRunner.Module());
|
||||
modules.addAll(LibModuleLoader.loadModules(cfgInjector));
|
||||
return cfgInjector.createChildInjector(modules);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user