Multiple Servlet injectors detected - Breaking Servlet Injection?

4,835 views
Skip to first unread message

Evan Ruff

unread,
Feb 5, 2011, 4:10:29 PM2/5/11
to google...@googlegroups.com
Guy guys!

I'm making some progress with the Guice. I've successfully implemented guice in all of my applications and have even migrated everything over to gwt-dispatch! I'm really beginning to get the hang of it and I'm starting to understand just how powerful it is. Now, I'm starting to push GIN down into all the GWT stuff... exciting! 

Everything is looking good (no turtles!) in development. I'm running into one (simple?) issue with deployment. I am running a single Tomcat 7 server for staging. I have two hosts (stage and admin) and am deploying three webapps (moose.war, charts.war, sem.war). These are all independent contexts. moose.war goes to the admin virtual host as ROOT, and the other two go to the stage host. When I deploy the first WAR to the server, it works great. As soon as I deploy the other, I get a WARNING in the log:

WARNING: Multiple Servlet injectors detected. This is a warning indicating that you have more than one GuiceFilter running in your web application. If this is deliberate, you may safely ignore this message. If this is NOT deliberate however, your application may not work as expected.

Now, if I go to access a servlet from either WAR, they both give 404s! They're using similar web.xml files with:
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>com.hs.***MY.LISTENER.HERE***</listener-class>
</listener>

I have tried altering the filter url-pattern but nothing seems to be helping the conflict. If I use Tomcat Manager to turn the hosts on/off as well as the various contexts, I can make them each work individually, but none at a time.

Is there a scoping issue somewhere? How can I get around this?!

Thanks!!

E





TJ Rothwell

unread,
Feb 5, 2011, 4:43:15 PM2/5/11
to google...@googlegroups.com
I find the error message here:

If you aren't installing multiple ServletModule's, then it might be occurring because the guice servlet jar is shared lib folder. I believe it should be located in your context's WEB-INF/lib

Hope that helps.

-- TJ






--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.

Evan Ruff

unread,
Feb 7, 2011, 7:51:35 AM2/7/11
to google-guice
Hey TJ,

This was the exact problem. Thanks for the pointer!

E

diogoeag

unread,
Mar 30, 2012, 10:10:59 AM3/30/12
to google...@googlegroups.com
Hi All,

We are using Jetty embedded and reuse lots of classes in a common lib that require guice.

Usually what we do in our GuiceFilter of each web app is:

public class GuiceConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        final Map<String, String> params = new HashMap<String, String>();
          params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.company.app.resources");

        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                serve("/*").with(GuiceContainer.class, params);
            }
        });
    }
}


Our problem is that when we are deploying the applications the following warning happens:

! GuiceFilter.setPipeline:87                      Multiple Servlet injectors detected. This is a warning indicating that you have more than one GuiceFilter running in your web application. If this is deliberate, you may safely ignore this message. If this is NOT deliberate however, your application may not work as expected.

And only one application is working after the server startup. Is there any other way to solve the problem rather than having the guice jar in each web app ? (this is not an option for us, because then we get lots of class cast exceptions due to our commons libs not being in the same classloader)

Cheers

Stuart McCulloch

unread,
Mar 30, 2012, 10:16:38 AM3/30/12
to google...@googlegroups.com
On 30 Mar 2012, at 22:10, diogoeag wrote:

Hi All,

We are using Jetty embedded and reuse lots of classes in a common lib that require guice.

Usually what we do in our GuiceFilter of each web app is:

public class GuiceConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        final Map<String, String> params = new HashMap<String, String>();
          params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.company.app.resources");

        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                serve("/*").with(GuiceContainer.class, params);
            }
        });
    }
}


Our problem is that when we are deploying the applications the following warning happens:

! GuiceFilter.setPipeline:87                      Multiple Servlet injectors detected. This is a warning indicating that you have more than one GuiceFilter running in your web application. If this is deliberate, you may safely ignore this message. If this is NOT deliberate however, your application may not work as expected.

And only one application is working after the server startup. Is there any other way to solve the problem rather than having the guice jar in each web app ? (this is not an option for us, because then we get lots of class cast exceptions due to our commons libs not being in the same classloader)

Cheers
 
On Saturday, February 5, 2011 9:10:29 PM UTC, Evan Ruff wrote:
Guy guys!

I'm making some progress with the Guice. I've successfully implemented guice in all of my applications and have even migrated everything over to gwt-dispatch! I'm really beginning to get the hang of it and I'm starting to understand just how powerful it is. Now, I'm starting to push GIN down into all the GWT stuff... exciting! 

Everything is looking good (no turtles!) in development. I'm running into one (simple?) issue with deployment. I am running a single Tomcat 7 server for staging. I have two hosts (stage and admin) and am deploying three webapps (moose.war, charts.war, sem.war). These are all independent contexts. moose.war goes to the admin virtual host as ROOT, and the other two go to the stage host. When I deploy the first WAR to the server, it works great. As soon as I deploy the other, I get a WARNING in the log:

WARNING: Multiple Servlet injectors detected. This is a warning indicating that you have more than one GuiceFilter running in your web application. If this is deliberate, you may safely ignore this message. If this is NOT deliberate however, your application may not work as expected.

Now, if I go to access a servlet from either WAR, they both give 404s! They're using similar web.xml files with:
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>com.hs.***MY.LISTENER.HERE***</listener-class>
</listener>

I have tried altering the filter url-pattern but nothing seems to be helping the conflict. If I use Tomcat Manager to turn the hosts on/off as well as the various contexts, I can make them each work individually, but none at a time.

Is there a scoping issue somewhere? How can I get around this?!

Thanks!!

E






--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-guice/-/dqZKSYO44tcJ.

diogoeag

unread,
Mar 30, 2012, 10:59:22 AM3/30/12
to google...@googlegroups.com
HI,

Thanks for the reply.

I've read the issue that you have mentioned and I didn't understand how can we solve the problem. 

Can you help me on how to solve my issue with the information that you gave me? 

Stuart McCulloch

unread,
Mar 30, 2012, 11:37:01 AM3/30/12
to google...@googlegroups.com
On 30 Mar 2012, at 22:59, diogoeag wrote:

HI,

Thanks for the reply.

I've read the issue that you have mentioned and I didn't understand how can we solve the problem. 

Can you help me on how to solve my issue with the information that you gave me? 

Right now each ServletModule requests _static_ injection on the GuiceFilter class (see InternalServletModule for the exact line), so the static pipeline field in GuiceFilter will only point back to the last injector that had a ServletModule. The static pipeline is used whenever you use the web.xml style of configuration.

That's why you see the warning message (happens when the GuiceFilter class sees multiple static injection) and probably why only one application is active.

One solution is to switch to a programmatic configuration approach - ie. get the GuiceFilter instance from each injector and register that with the web container. Then each GuiceFilter instance will use an injected pipeline (courtesy of the injector used to retrieve the GuiceFilter) over the static pipeline. You'll still see the warning message because the ServetModules will still request static injection, but can safely ignore it.

However, with the changes to guice-servlet suggested in comment 5 of issue 618 you could also extend the GuiceFilter class and still use the web.xml approach - only this time you'd name the subclass in the web.xml and have your own code in the constructor to bootstrap a different injector for each instance created of the filter (say using some filter parameter to load the appropriate servlet module class at runtime).

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-guice/-/RrkhzVk38j0J.

Diogo Guerra

unread,
Mar 30, 2012, 3:14:49 PM3/30/12
to google...@googlegroups.com
Hi, 

I'm trying to go with the first solution, but I'm having some problems. 

Our web.xml's files are like these:

  <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>com.acme.web.GuiceConfig</listener-class>
  </listener>
 

public class GuiceConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        final Map<String, String> params = new HashMap<String, String>();
          params.put(PackagesResourceConfig.PROPERTY_PACKAGES, " com.acme.web.resource");

        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                serve("/*").with(GuiceContainer.class, params);
            }
        });
    }
}


Now, I think that I need to remove from the web.xml the following lines:

  <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

And put some code in our GuiceConfig class to replace it. Although I didn't understand from you email how can I get the GuiceFilter from the injector that I'm creating. The Injector interface does not have any methods to get the GuiceFilter...  

Any ideas?

--Diogo

Stuart McCulloch

unread,
Mar 31, 2012, 11:45:48 AM3/31/12
to google...@googlegroups.com

injector.getInstance( GuiceFilter.class ) will give you a GuiceFilter instance that is specific to that injector, it will also use an injected pipeline instead of the static one

>>> params.put(**PackagesResourceConfig.**PROPERTY_PACKAGES,


>>> "com.company.app.resources");
>>>
>>> return Guice.createInjector(new ServletModule() {
>>> @Override
>>> protected void configureServlets() {

>>> serve("/*").with(**GuiceContainer.class, params);


>>> }
>>> });
>>> }
>>> }
>>>
>>>
>>> Our problem is that when we are deploying the applications the following
>>> warning happens:
>>>
>>> ! GuiceFilter.setPipeline:87 Multiple Servlet
>>> injectors detected. This is a warning indicating that you have more than
>>> one GuiceFilter running in your web application. If this is deliberate, you
>>> may safely ignore this message. If this is NOT deliberate however, your
>>> application may not work as expected.
>>>
>>> And only one application is working after the server startup. Is there
>>> any other way to solve the problem rather than having the guice jar in each
>>> web app ? (this is not an option for us, because then we get lots of class
>>> cast exceptions due to our commons libs not being in the same classloader)
>>>
>>>

>>> See http://code.google.com/p/**google-guice/issues/detail?id=**618#c2<http://code.google.com/p/google-guice/issues/detail?id=618#c2>


>>>
>>> Cheers
>>>
>>> On Saturday, February 5, 2011 9:10:29 PM UTC, Evan Ruff wrote:
>>>>
>>>> Guy guys!
>>>>
>>>> I'm making some progress with the Guice. I've successfully implemented
>>>> guice in all of my applications and have even migrated everything over to
>>>> gwt-dispatch! I'm really beginning to get the hang of it and I'm starting
>>>> to understand just how powerful it is. Now, I'm starting to push GIN down
>>>> into all the GWT stuff... exciting!
>>>>
>>>> Everything is looking good (no turtles!) in development. I'm running
>>>> into one (simple?) issue with deployment. I am running a single Tomcat 7
>>>> server for staging. I have two hosts (stage and admin) and am deploying
>>>> three webapps (moose.war, charts.war, sem.war). These are
>>>> all independent contexts. moose.war goes to the admin virtual host as ROOT,
>>>> and the other two go to the stage host. When I deploy the first WAR to the
>>>> server, it works great. As soon as I deploy the other, I get a WARNING in
>>>> the log:
>>>>
>>>> WARNING: Multiple Servlet injectors detected. This is a warning
>>>> indicating that you have more than one GuiceFilter running in your web
>>>> application. If this is deliberate, you may safely ignore this message. If
>>>> this is NOT deliberate however, your application may not work as expected.
>>>>
>>>> Now, if I go to access a servlet from either WAR, they both give 404s!
>>>> They're using similar web.xml files with:
>>>> <filter>

>>>> <filter-name>guiceFilter</**filter-name>
>>>> <filter-class>com.google.**inject.servlet.GuiceFilter</**filter-class>
>>>> </filter>
>>>>
>>>> <filter-mapping>
>>>> <filter-name>guiceFilter</**filter-name>


>>>> <url-pattern>/*</url-pattern>
>>>> </filter-mapping>
>>>>
>>>> <listener>

>>>> <listener-class>com.hs.***MY.**LISTENER.HERE***</listener-**class>

Diogo Guerra

unread,
Mar 31, 2012, 8:38:56 PM3/31/12
to google...@googlegroups.com
Hi,

Thanks for the reply.

Due to some restrictions in our project we woul like to try the second alternative if possible.

From what I've been able to unerstan in the code, we need to bootstrap a new pipeline for each instance of our class that extends GuiceFilter. 

But in you previous message you have said:

 "However, with the changes to guice-servlet suggested in comment 5 of issue 618 you could also extend the GuiceFilter class and still use the web.xml approach - only this time you'd name the subclass in the web.xml and have your own code in the constructor to bootstrap a different injector for each instance created of the filter (say using some filter parameter to load the appropriate servlet module class at runtime)."

Am I understanding the problem in a wrong way, or you have written injector instead of pipeline by mistake?

Is there any way to access the ManagedPipeline that the Injector injects in the setPipeline method?

I woul like to make a filter that we could provide in our common lib that does not use a static pipeline.

Also you say: "using some filter parameter to load the appropriate servlet module class at runtime"

So are you saying that my Filter needs to instantiate the Injector and then get the Pipeline from the Injector?

Cheers

--Diogo

diogoeag

unread,
Apr 1, 2012, 7:05:38 AM4/1/12
to google...@googlegroups.com
Hi Stuart, 

After some hours of sleep I think I got a solution. 

I've include it in the reply as an attachment. Although I'm not sure if this code is safe as I get the injected pipeline in the init method and store it in the instance of the filter. 

The idea is to only use this AppGuiceFilter in our web server to avoid the redefinition of the GuiceFilter.pipeline.   

Can you take a look at my code?

Thanks

--Diogo



>> For more options, visit this group at
>> http://groups.google.com/group/google-guice?hl=en.
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "google-guice" group.
>> To post to this group, send email to google...@googlegroups.com.
>> To unsubscribe from this group, send email to

>> For more options, visit this group at
>> http://groups.google.com/group/google-guice?hl=en.
>>
>
> --
> You received this message because you are subscribed to the Google Groups "google-guice" group.
> To post to this group, send email to google...@googlegroups.com.
> To unsubscribe from this group, send email to google-guice+unsubscribe@googlegroups.com.

> For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
>

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice+unsubscribe@googlegroups.com.
AppGuiceFilter.java
Reply all
Reply to author
Forward
0 new messages