Dynamically load plugins in new private injectors

Each plugin is given its own Guice injector that is isolated from the
main server, and from each other. Explicit bindings in the main server
are copied down into the plugin's private environment, making any
object that is bound in a module (e.g. GerritGlobalModule)
automatically available, but hiding anything that is loaded by a
just-in-time implicit binding.

These private injectors ensure plugins can't accidentally load a
just-in-time binding into the sysInjector and cause them to be unable
to garbage collect, or to confuse another plugin with a bogus binding.

Change-Id: I7bc54c84fba30381cfb58d24b88871b2714c335a
This commit is contained in:
Shawn O. Pearce
2012-05-08 19:16:30 -07:00
committed by gerrit code review
parent b4992582d6
commit 4c847cf912
15 changed files with 549 additions and 109 deletions

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.server.config.FactoryModule;
import com.google.gerrit.server.config.GerritRequestModule;
import com.google.gerrit.server.git.QueueProvider;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.plugins.StartPluginListener;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gerrit.server.util.RequestScopePropagator;
@@ -44,6 +45,7 @@ import com.google.gerrit.sshd.commands.DefaultCommandModule;
import com.google.gerrit.sshd.commands.QueryShell;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gerrit.util.cli.OptionHandlerUtil;
import com.google.inject.internal.UniqueAnnotations;
import com.google.inject.servlet.RequestScoped;
import org.apache.sshd.common.KeyPairProvider;
@@ -89,6 +91,9 @@ public class SshModule extends FactoryModule {
install(new LifecycleModule() {
@Override
protected void configure() {
bind(StartPluginListener.class)
.annotatedWith(UniqueAnnotations.create())
.to(SshPluginStarterCallback.class);
listener().to(SshLog.class);
listener().to(SshDaemon.class);
}