My favorites | Sign in
Project Home Downloads Wiki Issues Source
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 1966: Plugins that instantiate web servlet cause "404 not found" error when running Gerrit in tomcat.
8 people starred this issue and may be notified of changes. Back to list
Status:  Released
Owner:  ----
Closed:  Aug 2013


Sign in to add a comment
 
Reported by Ian.Kuml...@gmail.com, Jun 18, 2013
************************************************************
***** NOTE: THIS BUG TRACKER IS FOR GERRIT CODE REVIEW *****
***** DO NOT SUBMIT BUGS FOR CHROME, ANDROID, INTERNAL *****
***** ISSUES WITH YOUR COMPANY'S GERRIT SETUP, ETC.    *****
***** THOSE ISSUE BELONG IN DIFFERENT ISSUE TRACKERS!  *****
************************************************************

Affected Version: 2.5.x, 2.6-rcx

What steps will reproduce the problem?
1. Install and run gerrit in tomcat
2. Add a plugin that instantiates a web servelet to handle web access in some form
3. Try to access the main webpage.

What is the expected output? What do you see instead?

Expected: Normal gerrit and ability to access the pages provided by gerrit

Found: The servelet overrides gerrit's "servelet" and thus breaks both.

Please provide any additional information below.

This has been tested with both in house plugins and Lucas branch-network.

Everything works fine in Jetty.
Jul 10, 2013
Project Member #1 bassem.rabil
We have the same issue with Gitblit plugin
Jul 11, 2013
Project Member #2 david.pu...@sonymobile.com
 Issue 2004  has been merged into this issue.
Jul 11, 2013
Project Member #3 david.pu...@sonymobile.com
(No comment was entered for this change.)
Summary: Plugins that instantiate web servlet cause "404 not found" error when running Gerrit in tomcat. (was: plugins that uses web ui doesn't work with tomcat.)
Jul 11, 2013
Project Member #4 David.Os...@gmail.com
Has someone tried to verify that this issue still exists on current master (2.8)?
Jul 13, 2013
Project Member #5 David.Os...@gmail.com
i can reproduce the problem on stable-2.6.

The culprit seems to be that the ManagedServletPipeline-Singleton get overridden,
when Plugin with HTP Module is bound.

@Singleton
class ManagedServletPipeline
[...]

  public boolean service(ServletRequest request, ServletResponse response)
      throws IOException, ServletException {

89    //stop at the first matching servlet and service
90    for (ServletDefinition servletDefinition : servletDefinitions) {
91      if (servletDefinition.service(request, response)) {
92        return true;
93      }

Without plugins the pipeline contains 40 Gerrit core servlets in line 90.
And no one plugin owned, (only .*plugins.*).

With plugin loaded (with HTTP-Module), the servletDefinitions collected twice,
and the Gerrit core servlets get overridden by plugin owned. To request time,
there is only plugin owned requests, with pattern like "/log" (from plugin),
and clearly there is no match for pattern "/".

Interestingly and may be related to original problem: our own buildbot-plugin
doesn't even start on tomcat. While it is all fine
on jetty, the same plugin in tomcat fails to start, with 

class BuildbotModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(BuildbotConfig.class).toProvider(BuildbotConfigProvider.class).in(
                SINGLETON);
36        bind(BuildbotLogicControl.class).toProvider(
37                BuildbotLogicControlProvider.class).in(SINGLETON);
38        bind(AllProjectsName.class).toProvider(AllProjectsNameProvider.class);


1) A binding to com.google.gerrit.server.config.AllProjectsName was already configured at com.google.gerrit.server.plugins.PluginGuiceEnvironment$2.configure(PluginGuiceEnvironment.java:495).
  at org.libreoffice.ci.gerrit.buildbot.BuildbotModule.configure(BuildbotModule.java:38)

1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:154)

So the line PluginGuiceEnvironment.java:495 seems to behave differently on tomcat and jetty:

    return new AbstractModule() {
      @SuppressWarnings("unchecked")
      @Override
      protected void configure() {
        for (Map.Entry<Key<?>, Binding<?>> e : bindings.entrySet()) {
          Key<Object> k = (Key<Object>) e.getKey();
          Binding<Object> b = (Binding<Object>) e.getValue();
495          bind(k).toProvider(b.getProvider());
        }
      }
    };

On Jetty, when i uncomment the line 

38        bind(AllProjectsName.class).toProvider(AllProjectsNameProvider.class);

in Buildbot-plugin above, the plugin doesn't start with the error:

1) Could not find a suitable constructor in com.google.gerrit.server.config.AllProjectsName. 
Classes must have either one (and only one) constructor annotated with 
@Inject or a zero-argument constructor that is not private.
  at com.google.gerrit.server.config.AllProjectsName.class(AllProjectsName.java:23)
  while locating com.google.gerrit.server.config.AllProjectsName
    for field at org.libreoffice.ci.gerrit.buildbot.commands.VerifyCommand.allProjects(VerifyCommand.java:46)
  at com.google.gerrit.sshd.CommandModule.command(CommandModule.java:77)

1 error
	at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
	at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:154)

Jul 14, 2013
Project Member #6 David.Os...@gmail.com
OK i see what happens:

the problem seems to be related to guice-servlet bug or missing feature in handling of multiple filter pipelines.

When this method from startPlugin(PluginGuiceEnvironment env) called:
        httpInjector = sysInjector.createChildInjector(modules);

then we are getting this warning.

  //VisibleForTesting
  @Inject
  static void setPipeline(FilterPipeline pipeline) {

    // This can happen if you create many injectors and they all have their own
    // servlet module. This is legal, caveat a small warning.
    if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
=>        Logger.getLogger(GuiceFilter.class.getName()).warning(MULTIPLE_INJECTORS_WARNING);
    }

    // We overwrite the default pipeline
    GuiceFilter.pipeline = pipeline; 
  }

the pipeline from Gerrit core is clobbered and is never accessible again.
All Gerrit core servlet definitions are lost.

This is a known bug. I wonder why it doesn't happen in Jetty?

https://code.google.com/p/google-guice/issues/detail?id=635
https://groups.google.com/forum/#!msg/google-guice/wJBwzE5E7Y0/1LQJhCrmDnwJ

Aug 12, 2013
#9 sop@google.com
(No comment was entered for this change.)
Status: Submitted
Labels: FixedIn-2.6
Aug 12, 2013
Project Member #10 david.pu...@sonymobile.com
(No comment was entered for this change.)
Labels: -FixedIn-2.6 FixedIn-2.6.2
Dec 9, 2013
Project Member #11 david.pu...@sonymobile.com
(No comment was entered for this change.)
Labels: -FixedIn-2.6.2 FixedIn-2.8
Dec 9, 2013
Project Member #12 david.pu...@sonymobile.com
(No comment was entered for this change.)
Labels: -FixedIn-2.8 FixedIn-2.7
Dec 9, 2013
Project Member #13 david.pu...@sonymobile.com
(No comment was entered for this change.)
Status: Released
Nov 20, 2014
#14 sven.sel...@sonymobile.com
On Gerrit v2.10-rc0 in Tomcat:
WARN  com.google.gerrit.server.plugins.PluginLoader : Cannot load plugin gitiles
com.google.inject.CreationException: Guice creation errors:

1) A binding to com.google.gerrit.server.config.AllProjectsName was already configured at com.google.gerrit.server.plugins.PluginGuiceEnvironment$2.configure(PluginGuiceEnvironment.java:532).
  at com.googlesource.gerrit.plugins.gitiles.Module.configure(Module.java:50)

1 error
	at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:448
...
Feb 27, 2015
#15 sven.sel...@sonymobile.com
"This is a known bug. I wonder why it doesn't happen in Jetty?"
It does now!

Gerrit - v2.11-rc0
Gitiles - master (a4dd362 Update soy and gitiles-servlet to recent versions)
Under Jetty:

------------ "error_log" -----------

2015-02-27 10:58:14,476] WARN  com.google.gerrit.server.plugins.PluginLoader : Cannot load plugin gitiles
com.google.inject.CreationException: Unable to create injector, see the following errors:

1) A binding to com.google.gerrit.server.config.AllProjectsName was already configured at com.google.gerrit.server.plugins.PluginGuiceEnvironment$2.configure(PluginGuiceEnvironment.java:534) (via modules: com.google.gerrit.server.plugins.PluginGuiceEnvironment$1 -> com.google.gerrit.server.plugins.PluginGuiceEnvironment$2).
  at com.googlesource.gerrit.plugins.gitiles.Module.configure(Module.java:50)

1 error
        at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:448)
        at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)


Sign in to add a comment

Powered by Google Project Hosting