2 Replies Latest reply on May 15, 2009 3:19 AM by gena

    What be the status of Renderer in Asynchronous methods (timer, mdb); seems still broken in 2.1.2CR1

    aconn7

      I have read through the Jira 3555 thread and tried compiling release 2.1.1GA with the 2.1.2CR1 org.jboss.seam.ui.facelet.RendererRequest patch. I have also tried compiling and testing the 2.1.2CR1 release.


      Unfortunately all attempts fail at this place in the RendererRequest code:


         protected void setContextClassLoader() {
             // JBSEAM-3555 Quick fix
             // Set the context classloader to the cached one
             originalClassLoader = Thread.currentThread().getContextClassLoader();
             ServletContext ctx = request.getSession().getServletContext();
             WeakReference<ClassLoader> ref = (WeakReference<ClassLoader>)ctx.getAttribute("seam.context.classLoader");
             if (ref == null || ref.get() == null) {
                 // >>>  FAILS HERE <<< //
                 log.warn("Failed to bootstrap context classloader. Facelets may not work properly from MDBs");
             } else {
                 Thread.currentThread().setContextClassLoader(ref.get());
             }    
         }
      



      Additionally I am using JBOSS 4.2.3GA. No JSF is being used in my mail template.


      Where I have had great experience (for the most part) using SEAM for web development, I have virtually given up on it for anything that is outside of the servelet context like Asynchonous methods. For this reason, I am very careful now not to hijack my JEE session beans by making them dependent on SEAM bijection. They become unusable outside of the web context.


      For the time being, I have resorted to Freemarker generation to create my email body content. It's a simple lightweight solution but granted Seam Mail is SWEET, but too troublesome to use asynchronously. I wish I could :(

        • 1. Re: What be the status of Renderer in Asynchronous methods (timer, mdb); seems still broken in 2.1.2CR1
          gonorrhea

          Andy Conn wrote on Apr 11, 2009 19:24:


          Where I have had great experience (for the most part) using SEAM for web development, I have virtually given up on it for anything that is outside of the servelet context like Asynchonous methods. For this reason, I am very careful now not to hijack my JEE session beans by making them dependent on SEAM bijection. They become unusable outside of the web context.


          I have yet to try it myself, but I'm pretty sure that you can refactor the @In and other Seam-specific annotations into the components.xml or pages.xml (in this case, it would be components.xml).


          If you do that, then your classes won't break as easily when you move to another web/integration framework or app server.


          This is one of the strong points of the Spring framework.  When I took my Spring class several years ago, the instructor demonstrated how to add security and transactional functionality to a sample app without modifying the codebase (via AOP and xml).

          • 2. Re: What be the status of Renderer in Asynchronous methods (timer, mdb); seems still broken in 2.1.2CR1
            gena

            You can try to access the classloader on some strange way posted below. It works, but the coding is really bad - do not repeat it ;). If someone knows the better way, please post here!



            protected void setContextClassLoader() {
                      // JBSEAM-3555 Quick fix
                      // Set the context classloader to the cached one
                      originalClassLoader = Thread.currentThread()
                                                         .getContextClassLoader();
                      ServletContext ctx = request.getSession()
                                                         .getServletContext();
                      //accessing class loader of the webapp 
                            //really stupid code but works ;-(
                      Object o = null;
                      try {
                           Field f = ctx     .getClass()
                                               .getDeclaredField("context");
                           f.setAccessible(true);
                           o = f.get(ctx);
            
                           f = o     .getClass()
                                     .getDeclaredField("context");
                           f.setAccessible(true);
                           o = f.get(o);
            
                           o = o     .getClass()
                                     .getMethod("getLoader")
                                     .invoke(o);
            
                           o = o     .getClass()
                                     .getMethod("getClassLoader")
                                     .invoke(o);
            
                      } catch (Exception e) {
                           throw new RuntimeException(e);
                      }
            
                      WeakReference<ClassLoader> ref = new WeakReference<ClassLoader>((ClassLoader) o);
                      //ctx.getAttribute("seam.context.classLoader");
                      if (ref == null || ref.get() == null) {
                           log.warn("Failed to bootstrap context classloader. Facelets may not work properly from MDBs");
                      } else {
                           Thread     .currentThread()
                                     .setContextClassLoader(ref.get());
                      }
                 }