Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Update Eclipse compiler settings with Oxygen.3a Release (4.7.3a)
  Introduce mechanism to overload Gerrit core modules
  Move default memory cache implementation out of H2 package
  Introduce CacheImpl annotation
  Untangle persistent/memory cache implementations from each other
  H2CacheFactory: update internal caches list synchronously

Change-Id: I6c0952771b4e630a6628355f8cb2972ab7d12419
This commit is contained in:
David Pursehouse 2018-05-16 08:15:29 +09:00
commit 6ae012e010
19 changed files with 345 additions and 59 deletions

View File

@ -17,6 +17,7 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.APILeak=warning
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=ignore
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@ -91,6 +92,7 @@ org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning

View File

@ -0,0 +1,112 @@
// Copyright (C) 2018 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.cache.h2;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.Weigher;
import com.google.gerrit.server.cache.CacheBinding;
import com.google.gerrit.server.cache.h2.H2CacheImpl.ValueHolder;
import com.google.inject.TypeLiteral;
import java.util.concurrent.TimeUnit;
class H2CacheBindingProxy<K, V> implements CacheBinding<K, V> {
private static final String MSG_NOT_SUPPORTED =
"This is read-only wrapper. Modifications are not supported";
private final CacheBinding<K, V> source;
H2CacheBindingProxy(CacheBinding<K, V> source) {
this.source = source;
}
@Override
public Long expireAfterWrite(TimeUnit unit) {
return source.expireAfterWrite(unit);
}
@SuppressWarnings("unchecked")
@Override
public Weigher<K, V> weigher() {
Weigher<K, V> weigher = source.weigher();
if (weigher == null) {
return null;
}
// introduce weigher that performs calculations
// on value that is being stored not on ValueHolder
return (Weigher<K, V>)
new Weigher<K, ValueHolder<V>>() {
@Override
public int weigh(K key, ValueHolder<V> value) {
return weigher.weigh(key, value.value);
}
};
}
@Override
public String name() {
return source.name();
}
@Override
public TypeLiteral<K> keyType() {
return source.keyType();
}
@Override
public TypeLiteral<V> valueType() {
return source.valueType();
}
@Override
public long maximumWeight() {
return source.maximumWeight();
}
@Override
public long diskLimit() {
return source.diskLimit();
}
@Override
public CacheLoader<K, V> loader() {
return source.loader();
}
@Override
public CacheBinding<K, V> maximumWeight(long weight) {
throw new RuntimeException(MSG_NOT_SUPPORTED);
}
@Override
public CacheBinding<K, V> diskLimit(long limit) {
throw new RuntimeException(MSG_NOT_SUPPORTED);
}
@Override
public CacheBinding<K, V> expireAfterWrite(long duration, TimeUnit durationUnits) {
throw new RuntimeException(MSG_NOT_SUPPORTED);
}
@Override
public CacheBinding<K, V> loader(Class<? extends CacheLoader<K, V>> clazz) {
throw new RuntimeException(MSG_NOT_SUPPORTED);
}
@Override
public CacheBinding<K, V> weigher(Class<? extends Weigher<K, V>> clazz) {
throw new RuntimeException(MSG_NOT_SUPPORTED);
}
}

View File

@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.server.cache.CacheBinding;
import com.google.gerrit.server.cache.MemoryCacheFactory;
import com.google.gerrit.server.cache.PersistentCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheImpl.SqlStore;
import com.google.gerrit.server.cache.h2.H2CacheImpl.ValueHolder;
@ -50,7 +51,7 @@ import org.slf4j.LoggerFactory;
class H2CacheFactory implements PersistentCacheFactory, LifecycleListener {
private static final Logger log = LoggerFactory.getLogger(H2CacheFactory.class);
private final DefaultCacheFactory defaultFactory;
private final MemoryCacheFactory memCacheFactory;
private final Config config;
private final Path cacheDir;
private final List<H2CacheImpl<?, ?>> caches;
@ -62,11 +63,11 @@ class H2CacheFactory implements PersistentCacheFactory, LifecycleListener {
@Inject
H2CacheFactory(
DefaultCacheFactory defaultCacheFactory,
MemoryCacheFactory memCacheFactory,
@GerritServerConfig Config cfg,
SitePaths site,
DynamicMap<Cache<?, ?>> cacheMap) {
defaultFactory = defaultCacheFactory;
this.memCacheFactory = memCacheFactory;
config = cfg;
cacheDir = getCacheDir(site, cfg.getString("cache", null, "directory"));
h2CacheSize = cfg.getLong("cache", null, "h2CacheSize", -1);
@ -154,21 +155,19 @@ class H2CacheFactory implements PersistentCacheFactory, LifecycleListener {
@SuppressWarnings({"unchecked"})
@Override
public <K, V> Cache<K, V> build(CacheBinding<K, V> def) {
long limit = config.getLong("cache", def.name(), "diskLimit", 128 << 20);
public <K, V> Cache<K, V> build(CacheBinding<K, V> in) {
long limit = config.getLong("cache", in.name(), "diskLimit", in.diskLimit());
if (cacheDir == null || limit <= 0) {
return defaultFactory.build(def);
return memCacheFactory.build(in);
}
H2CacheBindingProxy<K, V> def = new H2CacheBindingProxy<>(in);
SqlStore<K, V> store =
newSqlStore(def.name(), def.keyType(), limit, def.expireAfterWrite(TimeUnit.SECONDS));
H2CacheImpl<K, V> cache =
new H2CacheImpl<>(
executor,
store,
def.keyType(),
(Cache<K, ValueHolder<V>>) defaultFactory.create(def, true).build());
executor, store, def.keyType(), (Cache<K, ValueHolder<V>>) memCacheFactory.build(def));
synchronized (caches) {
caches.add(cache);
}
@ -177,22 +176,24 @@ class H2CacheFactory implements PersistentCacheFactory, LifecycleListener {
@SuppressWarnings("unchecked")
@Override
public <K, V> LoadingCache<K, V> build(CacheBinding<K, V> def, CacheLoader<K, V> loader) {
long limit = config.getLong("cache", def.name(), "diskLimit", def.diskLimit());
public <K, V> LoadingCache<K, V> build(CacheBinding<K, V> in, CacheLoader<K, V> loader) {
long limit = config.getLong("cache", in.name(), "diskLimit", in.diskLimit());
if (cacheDir == null || limit <= 0) {
return defaultFactory.build(def, loader);
return memCacheFactory.build(in, loader);
}
H2CacheBindingProxy<K, V> def = new H2CacheBindingProxy<>(in);
SqlStore<K, V> store =
newSqlStore(def.name(), def.keyType(), limit, def.expireAfterWrite(TimeUnit.SECONDS));
Cache<K, ValueHolder<V>> mem =
(Cache<K, ValueHolder<V>>)
defaultFactory
.create(def, true)
.build((CacheLoader<K, V>) new H2CacheImpl.Loader<>(executor, store, loader));
memCacheFactory.build(
def, (CacheLoader<K, V>) new H2CacheImpl.Loader<>(executor, store, loader));
H2CacheImpl<K, V> cache = new H2CacheImpl<>(executor, store, def.keyType(), mem);
caches.add(cache);
synchronized (caches) {
caches.add(cache);
}
return cache;
}

View File

@ -0,0 +1,29 @@
// Copyright (C) 2018 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.cache.h2;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.ModuleImpl;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.PersistentCacheFactory;
@ModuleImpl(name = CacheModule.PERSISTENT_MODULE)
public class H2CacheModule extends LifecycleModule {
@Override
protected void configure() {
bind(PersistentCacheFactory.class).to(H2CacheFactory.class);
listener().to(H2CacheFactory.class);
}
}

12
gerrit-cache-mem/BUILD Normal file
View File

@ -0,0 +1,12 @@
java_library(
name = "mem",
srcs = glob(["src/main/java/**/*.java"]),
visibility = ["//visibility:public"],
deps = [
"//gerrit-extension-api:api",
"//gerrit-server:server",
"//lib:guava",
"//lib/guice",
"//lib/jgit/org.eclipse.jgit:jgit",
],
)

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.cache.h2;
package com.google.gerrit.server.cache.mem;
import com.google.common.base.Strings;
import com.google.common.cache.Cache;
@ -20,35 +20,21 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.cache.CacheBinding;
import com.google.gerrit.server.cache.ForwardingRemovalListener;
import com.google.gerrit.server.cache.MemoryCacheFactory;
import com.google.gerrit.server.cache.PersistentCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheImpl.ValueHolder;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
public class DefaultCacheFactory implements MemoryCacheFactory {
public static class Module extends LifecycleModule {
@Override
protected void configure() {
factory(ForwardingRemovalListener.Factory.class);
bind(DefaultCacheFactory.class);
bind(MemoryCacheFactory.class).to(DefaultCacheFactory.class);
bind(PersistentCacheFactory.class).to(H2CacheFactory.class);
listener().to(H2CacheFactory.class);
}
}
public class DefaultMemoryCacheFactory implements MemoryCacheFactory {
private final Config cfg;
private final ForwardingRemovalListener.Factory forwardingRemovalListenerFactory;
@Inject
public DefaultCacheFactory(
DefaultMemoryCacheFactory(
@GerritServerConfig Config config,
ForwardingRemovalListener.Factory forwardingRemovalListenerFactory) {
this.cfg = config;
@ -57,16 +43,16 @@ public class DefaultCacheFactory implements MemoryCacheFactory {
@Override
public <K, V> Cache<K, V> build(CacheBinding<K, V> def) {
return create(def, false).build();
return create(def).build();
}
@Override
public <K, V> LoadingCache<K, V> build(CacheBinding<K, V> def, CacheLoader<K, V> loader) {
return create(def, false).build(loader);
return create(def).build(loader);
}
@SuppressWarnings("unchecked")
<K, V> CacheBuilder<K, V> create(CacheBinding<K, V> def, boolean unwrapValueHolder) {
private <K, V> CacheBuilder<K, V> create(CacheBinding<K, V> def) {
CacheBuilder<K, V> builder = newCacheBuilder();
builder.recordStats();
builder.maximumWeight(cfg.getLong("cache", def.name(), "memoryLimit", def.maximumWeight()));
@ -74,17 +60,7 @@ public class DefaultCacheFactory implements MemoryCacheFactory {
builder = builder.removalListener(forwardingRemovalListenerFactory.create(def.name()));
Weigher<K, V> weigher = def.weigher();
if (weigher != null && unwrapValueHolder) {
final Weigher<K, V> impl = weigher;
weigher =
(Weigher<K, V>)
new Weigher<K, ValueHolder<V>>() {
@Override
public int weigh(K key, ValueHolder<V> value) {
return impl.weigh(key, value.value);
}
};
} else if (weigher == null) {
if (weigher == null) {
weigher = unitWeight();
}
builder.weigher(weigher);

View File

@ -0,0 +1,30 @@
// Copyright (C) 2018 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.cache.mem;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.server.ModuleImpl;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.ForwardingRemovalListener;
import com.google.gerrit.server.cache.MemoryCacheFactory;
@ModuleImpl(name = CacheModule.MEMORY_MODULE)
public class DefaultMemoryCacheModule extends FactoryModule {
@Override
protected void configure() {
factory(ForwardingRemovalListener.Factory.class);
bind(MemoryCacheFactory.class).to(DefaultMemoryCacheFactory.class);
}
}

View File

@ -49,6 +49,7 @@ junit_tests(
":gpg",
":testutil",
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-lucene:lucene",
"//gerrit-server:testutil",
"//lib:truth",

View File

@ -66,6 +66,7 @@ java_library(
REST_UTIL_DEPS = [
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-util-cli:cli",
"//lib:args4j",
"//lib/commons:dbcp",
@ -116,6 +117,7 @@ REST_PGM_DEPS = [
":init-api",
":util",
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-elasticsearch:elasticsearch",
"//gerrit-gpg:gpg",
"//gerrit-index:index",

View File

@ -50,10 +50,12 @@ 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.ModuleOverloader;
import com.google.gerrit.server.StartupChecks;
import com.google.gerrit.server.account.AccountDeactivator;
import com.google.gerrit.server.account.InternalAccountDirectory;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheModule;
import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
import com.google.gerrit.server.change.ChangeCleanupRunner;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.AuthConfigModule;
@ -412,7 +414,8 @@ public class Daemon extends SiteProgram {
modules.add(new SearchingChangeCacheImpl.Module(slave));
modules.add(new InternalAccountDirectory.Module());
modules.add(new DefaultPermissionBackendModule());
modules.add(new DefaultCacheFactory.Module());
modules.add(new DefaultMemoryCacheModule());
modules.add(new H2CacheModule());
modules.add(cfgInjector.getInstance(MailReceiver.Module.class));
if (emailModule != null) {
modules.add(emailModule);
@ -472,7 +475,8 @@ public class Daemon extends SiteProgram {
if (testSysModule != null) {
modules.add(testSysModule);
}
return cfgInjector.createChildInjector(modules);
return cfgInjector.createChildInjector(
ModuleOverloader.override(modules, LibModuleLoader.loadModules(cfgInjector)));
}
private boolean migrateToNoteDb() {

View File

@ -38,7 +38,8 @@ import com.google.gerrit.server.account.GroupIncludeCacheImpl;
import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.account.externalids.ExternalIdModule;
import com.google.gerrit.server.cache.CacheRemovalListener;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheModule;
import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.change.ChangeKindCacheImpl;
import com.google.gerrit.server.change.MergeabilityCacheImpl;
@ -155,7 +156,8 @@ public class BatchProgramModule extends FactoryModule {
install(new BatchGitModule());
install(new DefaultPermissionBackendModule());
install(new DefaultCacheFactory.Module());
install(new DefaultMemoryCacheModule());
install(new H2CacheModule());
install(new ExternalIdModule());
install(new GroupModule());
install(new NoteDbModule(cfg));

View File

@ -169,6 +169,7 @@ TESTUTIL_DEPS = [
"//gerrit-common:annotations",
"//gerrit-common:server",
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-extension-api:api",
"//gerrit-gpg:gpg",
"//gerrit-index:index",

View File

@ -0,0 +1,34 @@
// Copyright (C) 2018 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.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
@Inherited
/**
* Use this annotation to mark module as being swappable with implementation from {@code
* gerrit.installModule}. Note that module with this annotation shouldn't be part of circular
* dependency with any existing module.
*/
public @interface ModuleImpl {
String name();
}

View File

@ -0,0 +1,70 @@
// Copyright (C) 2018 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 com.google.inject.Module;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ModuleOverloader {
public static List<Module> override(List<Module> modules, List<Module> overrideCandidates) {
if (overrideCandidates == null || overrideCandidates.isEmpty()) {
return modules;
}
// group candidates by annotation existence
Map<Boolean, List<Module>> grouped =
overrideCandidates
.stream()
.collect(
Collectors.groupingBy(m -> m.getClass().getAnnotation(ModuleImpl.class) != null));
// add all non annotated libs to modules list
List<Module> libs = grouped.get(Boolean.FALSE);
if (libs != null) {
modules.addAll(libs);
}
List<Module> overrides = grouped.get(Boolean.TRUE);
if (overrides == null) {
return modules;
}
// swipe cache implementation with alternative provided in lib
return modules
.stream()
.map(
m -> {
ModuleImpl a = m.getClass().getAnnotation(ModuleImpl.class);
if (a == null) {
return m;
}
return overrides
.stream()
.filter(
o ->
o.getClass()
.getAnnotation(ModuleImpl.class)
.name()
.equalsIgnoreCase(a.name()))
.findFirst()
.orElse(m);
})
.collect(Collectors.toList());
}
private ModuleOverloader() {}
}

View File

@ -31,6 +31,9 @@ import java.lang.reflect.Type;
/** Miniature DSL to support binding {@link Cache} instances in Guice. */
public abstract class CacheModule extends FactoryModule {
public static final String MEMORY_MODULE = "cache-memory";
public static final String PERSISTENT_MODULE = "cache-persistent";
private static final TypeLiteral<Cache<?, ?>> ANY_CACHE = new TypeLiteral<Cache<?, ?>>() {};
/**

View File

@ -29,7 +29,8 @@ import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheModule;
import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.config.AllUsersName;
@ -215,7 +216,8 @@ public class InMemoryModule extends FactoryModule {
return MoreExecutors.newDirectExecutorService();
}
});
install(new DefaultCacheFactory.Module());
install(new DefaultMemoryCacheModule());
install(new H2CacheModule());
install(new FakeEmailSender.Module());
install(new SignedTokenEmailTokenVerifier.Module());
install(new GpgModule(cfg));

View File

@ -8,6 +8,7 @@ java_library(
visibility = ["//visibility:public"],
deps = [
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-common:annotations",
"//gerrit-common:server",
"//gerrit-extension-api:api",

View File

@ -6,6 +6,7 @@ java_library(
visibility = ["//visibility:public"],
deps = [
"//gerrit-cache-h2:cache-h2",
"//gerrit-cache-mem:mem",
"//gerrit-elasticsearch:elasticsearch",
"//gerrit-extension-api:api",
"//gerrit-gpg:gpg",

View File

@ -32,10 +32,12 @@ 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.ModuleOverloader;
import com.google.gerrit.server.StartupChecks;
import com.google.gerrit.server.account.AccountDeactivator;
import com.google.gerrit.server.account.InternalAccountDirectory;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.cache.h2.H2CacheModule;
import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
import com.google.gerrit.server.change.ChangeCleanupRunner;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.AuthConfigModule;
@ -321,7 +323,8 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi
modules.add(new SearchingChangeCacheImpl.Module());
modules.add(new InternalAccountDirectory.Module());
modules.add(new DefaultPermissionBackendModule());
modules.add(new DefaultCacheFactory.Module());
modules.add(new DefaultMemoryCacheModule());
modules.add(new H2CacheModule());
modules.add(cfgInjector.getInstance(MailReceiver.Module.class));
modules.add(new SmtpEmailSender.Module());
modules.add(new SignedTokenEmailTokenVerifier.Module());
@ -367,8 +370,8 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi
modules.add(new GarbageCollectionModule());
modules.add(new ChangeCleanupRunner.Module());
modules.add(new AccountDeactivator.Module());
modules.addAll(LibModuleLoader.loadModules(cfgInjector));
return cfgInjector.createChildInjector(modules);
return cfgInjector.createChildInjector(
ModuleOverloader.override(modules, LibModuleLoader.loadModules(cfgInjector)));
}
private Module createIndexModule() {