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
On Sunday, April 1, 2012 1:38:56 AM UTC+1, diogoeag wrote:
>
> 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
>
>
> On Sat, Mar 31, 2012 at 4:45 PM, Stuart McCulloch <[email protected]>wrote:
>
>> On 31 Mar 2012, at 03:14, Diogo Guerra wrote:
>>
>> > 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...
>>
>> 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
>>
>> > Any ideas?
>> >
>> > --Diogo
>> >
>> >
>> > On Fri, Mar 30, 2012 at 4:37 PM, Stuart McCulloch <[email protected]>
>> wrote:
>> >
>> >> 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).
>> >>
>> >> On Friday, March 30, 2012 3:16:38 PM UTC+1, Stuart McCulloch wrote:
>> >>>
>> >>> 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)
>> >>>
>> >>>
>> >>> 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>
>> >>>> </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/-/RrkhzVk38j0J.
>> >> To post to this group, send email to [email protected].
>> >> To unsubscribe from this group, send email to
>> >> [email protected].
>> >> 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 [email protected].
>> >> To unsubscribe from this group, send email to
>> >> [email protected].
>> >> 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 [email protected].
>> > To unsubscribe from this group, send email to
>> [email protected].
>> > 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 [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> 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 view this discussion on the web visit
https://groups.google.com/d/msg/google-guice/-/fGcBEBtGvEQJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.
package com.google.inject.servlet;
import java.io.IOException;
import java.lang.ref.WeakReference;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Diogo Guerra
*/
public class AppGuiceFilter extends GuiceFilter {
// lock to ensure that all webapps using this filter will not access to the static pipeline concurrently.
// this lock will only work if all web apps use this filter. This lock is not safe if other app uses GuiceFilter.
private static final Object lock = new Object();
// local instance of the pipeline.
volatile FilterPipeline localPipeline;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// this method is a copy of the one in GuiceFilter, but using the local pipeline instead of the static one.
Context previous = localContext.get();
try {
localContext.set(new Context((HttpServletRequest) servletRequest,
(HttpServletResponse) servletResponse));
//dispatch across the servlet pipeline, ensuring web.xml's filterchain is honored
localPipeline.dispatch(servletRequest, servletResponse, filterChain);
} finally {
localContext.set(previous);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
synchronized (lock) {
//define the localPipeline with the injected pipeline.
localPipeline = pipeline;
// Store servlet context in a weakreference, for injection
servletContext = new WeakReference<ServletContext>(filterConfig.getServletContext());
localPipeline.initPipeline(filterConfig.getServletContext());
//reset the static pipeline
pipeline = new DefaultFilterPipeline();
}
}
@Override
public void destroy() {
try {
// destroy the local pipeline instead of the static one.
localPipeline.destroyPipeline();
} finally {
reset();
servletContext.clear();
}
}
}