New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PippoFilter as Guice Filter #369

Closed
kiru opened this Issue Jun 3, 2017 · 7 comments

Comments

Projects
None yet
2 participants
@kiru

kiru commented Jun 3, 2017

I would like to use Pippo with Guice, but not the way described here: http://www.pippo.ro/mod/guice.html
Instead I use the GuiceServlet, Gucie allows to configure all the filters and servlets without the need for web.xm ( expect for GuiceFilter), as described here: https://github.com/google/guice/wiki/ServletModule

I use the ServletModule from Guice and try to add the PippoFilter like this:

filter("/*").through(GuicePippoFilter.class);
bind(GuicePippoFilter.class).in(Scopes.SINGLETON);

Unfortunately I get the following exception:

java.lang.NullPointerException: null
	at ro.pippo.core.PippoFilter.initFilterPathFromWebXml(PippoFilter.java:216) ~[pippo-core-1.4.0.jar:na]
	at ro.pippo.core.PippoFilter.initFilterPath(PippoFilter.java:195) ~[pippo-core-1.4.0.jar:na]
	at ro.pippo.core.PippoFilter.init(PippoFilter.java:96) ~[pippo-core-1.4.0.jar:na]
	at io.kiru.GuicePippoFilter.init(GuicePippoFilter.java:37) [main/:na]
	at com.google.inject.servlet.FilterDefinition.init(FilterDefinition.java:114) [guice-servlet-3.0.jar:na]
	at com.google.inject.servlet.ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:98) [guice-servlet-3.0.jar:na]
	at com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:172) [guice-servlet-3.0.jar:na]
	at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:138) [jetty-servlet-9.2.5.v20141112.jar:9.2.5.v20141112]
	at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:852) [jetty-servlet-9.2.5.v20141112.jar:9.2.5.v20141112]
... skipped 

GuiceFilter looks like this:


public class GuicePippoFilter extends PippoFilter{
    @Inject
    public GuicePippoFilter(MyApplication myApplication) {
        setApplication(myApplication);
        /*
        // This workaround works for now
        Object cc = this;

        try {
            Field f1 = cc.getClass().getSuperclass().getDeclaredField("filterPath");
            f1.setAccessible(true);
            f1.set(cc, "");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        */
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        super.init(filterConfig);
    }
}

I guess Pippo expects a web.xml configuration and reads the properties from web.xml and fails. My workaround for now is to set the "filterPath" string to empty.
Is it possible to fix this properly? Maybe add a protected setter for filterPath so I can set it from the outside.

@decebals

This comment has been minimized.

Member

decebals commented Jun 6, 2017

I was in a mini vacation. I will try a look and I will come back with a response/solution.

@decebals

This comment has been minimized.

Member

decebals commented Jun 6, 2017

@decebals

This comment has been minimized.

Member

decebals commented Jun 7, 2017

It's not a problem for me to add a a new protected void setFilterPath(String filterPath) method in PippoFilter (I will add this method asap) but I wish to understand more about Guice in web applications.
I will try to use Guice in one of my next web applications based on Pippo. In present, I don't use Guice in my projects but I think that Guice is a good DI library (for web applications, also). For now I don't understand very clear the difference between the approach with add Guice via add ServletContextListener/GuiceServletContextListener (see my previous comment) and add Guice via ServletModule (the approach used by you).

@decebals decebals closed this in f4fdcee Jun 7, 2017

@kiru

This comment has been minimized.

kiru commented Jun 9, 2017

Hello @decebals

I had no time to response quicker.
I think ServletModule ist just a "wrapper" around ServletContext, in the sense that you can add your filter directly to ServletContext. Adding them via ServletModule gives you access to DI-features in your Filter/Servlet.

In your example (https://dzone.com/articles/pippo-and-jersey-jax-rs), you get your dependency from the ServletContext

return ((JerseyApplication) servletContext.getAttribute(WebServer.PIPPO_APPLICATION)).getContactService();

With ServletModule (assuming you would have used Guice ) you might just inject it directly:

@Inject
private ContactService contactService;

But your example is a different one, you use Pippo and add the Jersey Servlet additionally. My use case is, that I have an application with few servlets and want to add the PippoFilter.

Is there maybe a PippoServlet, so I can add it directly instead of the Filter (with the Filter, I have another problem, that if Pippo cannot find a routing, then it'll send a 404, but I would like to follow the filter chain instead ).

Thank you,
Kiru

@decebals

This comment has been minimized.

Member

decebals commented Jun 9, 2017

Thanks for your explanation.

In your example (https://dzone.com/articles/pippo-and-jersey-jax-rs), you get your dependency from the ServletContext

The reason is because I don't use a DI library in that demo and I need to "share" the ContactService from my application with rest application (built with Jersey JAX-RS).

Is there maybe a PippoServlet, ...

See PippoServlet.

... with the Filter, I have another problem, that if Pippo cannot find a routing, then it'll send a 404, but I would like to follow the filter chain instead

I can take a look to see if I can do something in this direction. I use filters from inside (simple routes) of my application. If I need to add external filters I make it via ServletContextListener (see https://github.com/decebals/pippo-demo/tree/master/pippo-demo-servlet) or WebServerInitializer. For more details see #321.

And by the way, related to approach described in http://www.pippo.ro/mod/guice.html. Maybe the code snippet and the explanation are not the best. For example, that section describe only how to use Guice in controllers. When I use plain routes approach (without controllers) with DI (Spring) in my application, I instantiate my Application class via DI and pass it to PippoServer(new PippoServer(DI.getApplicationInstance()).start() in static main method). In this mode all @Inject annotation from application are resolved by DI. Another approach is described in https://groups.google.com/forum/#!topic/pippo-java/Yr6Q-jM8PNE.

Pippo is very flexible in my opinion and you can achieve a behavior on several ways.

@kiru

This comment has been minimized.

kiru commented Jun 9, 2017

Awesome, I have not seen PippoServlet. Actually, that is what I've been searching for. Just added these to my servlet-bindings and it works as expected:

serve("/*").with(GuicePippoServlet.class);
bind(GuicePippoServlet.class).in(Scopes.SINGLETON);

I had to subclass PippoServlet, so I can inject the Application:

public class GuicePippoServlet extends PippoServlet {
    @Inject
    public GuicePippoServlet(Application application) {
        super();
        setApplication(application);
    }
}

And by the way, related to approach described in http://www.pippo.ro/mod/guice.html. Maybe the code snippet and the explanation are not the best.

I saw that documentation, but it focuses on using Guice to Inject dependencies ( and not using Pippo as a dependency in an existing application ).

@decebals

This comment has been minimized.

Member

decebals commented Jun 9, 2017

Awesome, I have not seen PippoServlet. Actually, that is what I've been searching for. Just added these to my servlet-bindings and it works as expected ...

I am glad to see that your problem is resolved so easy 😄

I saw that documentation, but it focuses on using Guice to Inject dependencies ( and not using Pippo as a dependency in an existing application ).

You are right.

If you encounter other problems, please let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment