Example for Using Method Interception?

43 views
Skip to first unread message

Craig Phillips

unread,
Aug 6, 2013, 12:06:40 AM8/6/13
to mojav...@googlegroups.com
Any examples of using method interception with Mojave MVC? I see there is an @InterceptedBy annotation which takes a class as a value argument however no combination I've tried has worked so far.

I wasn't able to find any kind of documentation anywhere so I'm just guessing here but I had assumed that the class being referenced in the @InterceptedBy annotation needs to work like standard Guice method interceptors (implementing the org.aopalliance.intercept.MethodInterceptor class, etc.) but when I tried that - both on the controller class itself as well as directly on action methods themselves - I'm just getting some fairly unenlightening exceptions:

org.apache.jasper.JasperException: javax.servlet.ServletException: Servlet.init() for servlet FrontController threw exception

 

 org
.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)

 org
.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:455)

 org
.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

 org
.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)


 

root cause

javax
.servlet.ServletException: Servlet.init() for servlet FrontController threw exception

 org
.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:746)

 org
.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:716)

 org
.apache.jsp.index_jsp._jspService(index_jsp.java:64)

 org
.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)

 org
.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)

 org
.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

 org
.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)


 

root cause

java
.lang.NullPointerException

 org
.mojavemvc.core.FrontControllerInitializer.createInitControllers(FrontControllerInitializer.java:230)

 org
.mojavemvc.FrontController.init(FrontController.java:81)

 javax
.servlet.GenericServlet.init(GenericServlet.java:160)

 org
.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:746)

 org
.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:716)

 org
.apache.jsp.index_jsp._jspService(index_jsp.java:64)

 org
.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)

 org
.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)

 org
.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

 org
.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)


Any examples of this in action?

I also tried specifying a method interceptor in my custom Guice Module but that was also producing exceptions so no luck their either.

In the end, I'm trying to use method interception to implement security at the controller action level so there would be other workarounds but it seems like the framework is supposed to support this and I'm just doing something incorrectly.

Luis Antunes

unread,
Aug 6, 2013, 1:34:03 AM8/6/13
to mojav...@googlegroups.com
Hi Craig,

I agree there is a lack of documentation around this feature. I will certainly try to get more documentation on the web site soon. For now, I can point you to an example interceptor class that can be found in the tests for the core module:


The basic idea is that @InterceptedBy takes, as its parameter, the class name of the interceptor which will intercept actions on the annotated class. An interceptor is simply a POJO with a @BeforeAction and/or @AfterAction method. That is, an interceptor is a class that has a method, or methods, annotated with @BeforeAction and/or @AfterAction. Optionally, these methods may take a RequestContext parameter (for example, see https://github.com/lantunes/mojave/blob/master/mojave-core/src/test/java/org/mojavemvc/tests/interceptors/Interceptor10.java). The Mojave interceptors do not work with aopalliance.

The error you are seeing occurs during startup, when the framework analyses the app configuration, and encounters a likely invalid interceptor. I agree that the error message should be more informative. You can also try enabling debug level logging to see if you can get more detailed messages.

I hope this helps. I'm curious as to why you weren't able to get interception working using the Guice module approach. If you could provide a code snippet and/or a stack trace for that approach, that would be great.

Thanks! 

Craig Phillips

unread,
Aug 7, 2013, 10:48:42 AM8/7/13
to mojav...@googlegroups.com
Luis-

Thanks a ton for the quick response!

The @BeforeAction annotation does the trick. I'm now seeing my interceptor being called whenever one of the controller's action methods is triggered. It looks like the RequestContext that is passed to the annotated method doesn't have any information about which method was called. It looks like the full http request object is in there so I should be able to figure it out based on controller name and path - is that how you would recommend doing that? I'm trying to find which method was called so that I can inspect which other annotations are on that method to determine how the interception behaves (explained a bit more below.)

As far using interception via the Guice module goes, here's what I was trying. I have an annotation that I created called Secured. The idea being, that this annotation is placed before a method and when that method is called, a check is made (through a class I put together called Bouncer which implements the org.aopalliance.intercept.MethodInterceptor interface) to see if an authenticated User object is present in the current session. If not, the user is kicked over to the login page which will authenticate the user and then place the appropriate object in their session. I've registered that with the following call in my Guice module (which I've registered via the guice-modules init parameter):

java.lang.NullPointerException

        at org.mojavemvc.core.HttpActionInvoker.invokeActionMethod(HttpActionInvoker.java:130)


        at org.mojavemvc.core.HttpActionInvoker.invokeAction(HttpActionInvoker.java:79)


        at org.mojavemvc.core.RequestProcessor.process(RequestProcessor.java:58)


        at org.mojavemvc.FrontController.processRequest(FrontController.java:227)


        at org.mojavemvc.FrontController.doGet(FrontController.java:105)


        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)


        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)


        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)


        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)


        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)


        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)


        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)


        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)


        at org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:746)


        at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:716)


        at org.apache.jsp.index_jsp._jspService(index_jsp.java:64)


        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)


        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)


        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)


        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)


        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)


        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)


        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)


        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)


        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)


        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)


        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)


        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)


        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)


        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)


        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)


        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)


        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)


        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)


        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)


        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)


        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)


        at java.lang.Thread.run(Thread.java:680)

 

root cause

java
.lang.NullPointerException

 org
.mojavemvc.core.FrontControllerInitializer.createInitControllers(FrontControllerInitializer.java:230)

 org
.mojavemvc.FrontController.init(FrontController.java:81)

 javax
.servlet.GenericServlet.init(GenericServlet.java:160)

 org
.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:746)

 org
.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:716)

 org
.apache.jsp.index_jsp._jspService(index_jsp.java:64)

 org
.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)

 org
.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)

 org
.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

 org
.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

 javax
.servlet.http.HttpServlet.service(HttpServlet.java:728)

I've used that interception method before with a different MVC framework and it was working correctly there so I believe the code itself works correctly.

Not sure if that helps or not but if I can get you any more information, just let me know what I can do.

Thanks again!

Craig

Craig Phillips

unread,
Aug 7, 2013, 10:52:32 AM8/7/13
to mojav...@googlegroups.com
Was just re-reading that post and realized I mangled it. That big stack trace is what I'm seeing when I try to use the Guice method interception technique which matches based on annotations.

The actual call that I use to set up that registration is:

bindInterceptor(Matchers.any(), Matchers.annotatedWith(Secured.class), new Bouncer());

Let me know if that needs any further clarification,

Craig

Luis Antunes

unread,
Aug 8, 2013, 9:42:36 AM8/8/13
to mojav...@googlegroups.com
HI Craig,

The RequestContext object has getAction() and getController() methods. This getAction() method returns a String, which is the name of the action. That is, if your action method is annotated with @Action("foo"), for example, RequestContext.getAction() should return "foo". If it is annotated with just @Action, it should return the name of the Java method that is annotated. The same sort of thing goes for the getController() method. Have you tried these methods and run into problems? You can certainly use the HttpServletRequest object itself, however, if you prefer. It contains that same information. There is also the RequestContext.getParameters() method, which should provide the parameters, if any, given to the action method when it was invoked.

In terms of the Guice module error, it's hard for me to say by looking at that stack trace. In this case I'd probably need to see some source code to try to understand what is going on. I understand that source code is often proprietary and confidential, so I understand if you cannot share it. 

Hope this helps, and feel free to ask if you come across any more issues.

Thanks!

Craig Phillips

unread,
Aug 8, 2013, 12:51:04 PM8/8/13
to mojav...@googlegroups.com
The getAction() and getController() methods will work perfectly. When I was looking at it last I somehow missed the getAction() method. Not enough sleep, I guess. :-)

I'm not going to worry about the Guice module error. You've got an alternate approach for method interception that does the trick. Thanks a ton!

Craig
Reply all
Reply to author
Forward
0 new messages