5 Replies Latest reply on Apr 4, 2007 2:26 PM by tfvaida

    ResourceServlet with injection

    dilator

      Hi guys,

      Just been having a little play with the ResourceServlet - looks pretty sweet - I got some resources serving in a couple of minutes!

      I initially copied code from CaptchaImage, then wanted to get a bit of injection going, so removed the @Intercept(NEVER) annotation.

      20:04:31,140 ERROR [[SeamResourceServlet]] Allocate exception for servlet SeamResourceServlet
      java.lang.IllegalArgumentException: Protected method: setServletContext(Ljavax/servlet/ServletContext;)V
       at net.sf.cglib.proxy.MethodProxy$1.invoke(MethodProxy.java:55)
       at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:89)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:57)
       at org.jboss.seam.interceptors.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:34)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
       at org.jboss.seam.interceptors.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:47)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
       at org.jboss.seam.interceptors.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:27)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:69)
       at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:113)
       at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:145)
       at org.jboss.seam.intercept.JavaBeanInterceptor.intercept(JavaBeanInterceptor.java:80)
       at uk.co.this.isnt.really.my.domain.AttachmentResource$$EnhancerByCGLIB$$5ca4ae58.setServletContext(<generated>)
       at org.jboss.seam.servlet.ResourceServlet.loadResourceProviders(ResourceServlet.java:48)
       at org.jboss.seam.servlet.ResourceServlet.init(ResourceServlet.java:35)
       at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1105)
       at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:757)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:130)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)



      Looks like the CGLIB enhanced class doesnt like calling protected methods... I overrided the get+setServletContext with public modifiers, and also the getResourcePath. And now it seems to work fine.

      So my question is - is it safe / intended to do injection like this (I hope so!), its a bit different to the way the CaptchaImage works, but presumably
      because the CaptchaImage doesnt have any dependencies, it doesnt need it.

      And generally, are there any other bits i should know about when creating resources like this?

      Cheers - Ben

        • 1. Re: ResourceServlet with injection
          dilator

          Also presumably i still need to call Lifecycle.beginRequest if want to access 'lower' scopes, which means i can only inject application scope and auto-create components (e.g. entity manager)?

          • 2. Re: ResourceServlet with injection
            gavin.king

            I don't think you should be trying to use a ResourceServlet as an ordinary Seam component. Use it for "special" things only.

            • 3. Re: ResourceServlet with injection
              dilator

              Yeah i quite agree, I was just poking around really which made me think :)
              I was only really interested in injection because it looks neat...

              • 4. Re: ResourceServlet with injection
                tfvaida

                What if you need something like injection? I have a case where I need to access some application/persistence level information to allow my ResourceServlet to access an internal protected store of files and stream them through to the end client.

                How do I get access to these components?

                • 5. Re: ResourceServlet with injection
                  tfvaida

                  Oops - nevermind - I figured out how to get around this:

                  First - you cannot inject anything other than the logger, PeristenceManager and such throw errors.

                  You will have the application context which as the example code shows can be grabbed from the static Contexts.getApplicationContext() function.

                  To get any other Seam objects you must go through a component - and it must be through the 'local' interface EJB style ie:

                  DocumentManager docManager = (DocumentManager) Component.getInstance("documentManager");
                  


                  Where in this case the beans are a stateful session bean and the local interface like this:

                  @Name("documentManager")
                  @Stateful(...)
                  ...
                  class DocumentManagerBean implements DocumentManager {
                  ...
                  
                  

                  and


                  @Local
                  interface DocumentManager {
                  ...