Uploaded image for project: 'Crowd Data Center'
  1. Crowd Data Center
  2. CWD-2755

Using freemarker result-type with webwork tags causes NullPointerException

    XMLWordPrintable

Details

    • Bug
    • Resolution: Obsolete
    • Low
    • None
    • 2.3.4
    • None
    • None

    Description

      So I am developing a plugin, and I have created an Action and a freemarker file as the result type that contains webwork tags for dealing with forms, etc. However because Crowd has opted to create the templates in JSP, there is a bug in the Freemarker Result type that does not properly set up a PageContext on the stack, thus resulting in a NullPointerException. The stacktrace is:

      [INFO] [talledLocalContainer] java.lang.NullPointerException
      [INFO] [talledLocalContainer] 	at com.opensymphony.webwork.components.template.JspTemplateEngine.renderTemplate(JspTemplateEngine.java:43)
      [INFO] [talledLocalContainer] 	at com.opensymphony.webwork.components.UIBean.mergeTemplate(UIBean.java:642)
      [INFO] [talledLocalContainer] 	at com.opensymphony.webwork.components.ClosingUIBean.start(ClosingUIBean.java:43)
      [INFO] [talledLocalContainer] 	at com.opensymphony.webwork.views.freemarker.tags.CallbackWriter.onStart(CallbackWriter.java:54)
      [INFO] [talledLocalContainer] 	at freemarker.core.Environment.visit(Environment.java:230)
      [INFO] [talledLocalContainer] 	at freemarker.core.UnifiedCall.accept(UnifiedCall.java:116)
      [INFO] [talledLocalContainer] 	at freemarker.core.Environment.visit(Environment.java:196)
      [INFO] [talledLocalContainer] 	at freemarker.core.MixedContent.accept(MixedContent.java:92)
      [INFO] [talledLocalContainer] 	at freemarker.core.Environment.visit(Environment.java:196)
      [INFO] [talledLocalContainer] 	at freemarker.core.Environment.process(Environment.java:176)
      [INFO] [talledLocalContainer] 	at freemarker.template.Template.process(Template.java:232)
      [INFO] [talledLocalContainer] 	at com.opensymphony.webwork.views.freemarker.FreemarkerResult.doExecute(FreemarkerResult.java:214)
      

      There are two possible workarounds to this situation:
      1) Modify the FreemarkerResult class to properly initialize the PageContext object, with some code like (borrowed from VelocityResult):

      public class FreemarkerResultExt extends FreemarkerResult {
          private static final long serialVersionUID = 65184865308474038L;
      
          @Override
          public void doExecute(String location, ActionInvocation invocation)
                  throws IOException, TemplateException {
      
              HttpServletRequest request = ServletActionContext.getRequest();
              HttpServletResponse response = ServletActionContext.getResponse();
              JspFactory jspFactory = null;
              Servlet servlet = JspSupportServlet.jspSupportServlet;
      
              boolean usedJspFactory = false;
              PageContext pageContext = (PageContext) ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT);
      
              if (pageContext == null && servlet != null) {
                  jspFactory = JspFactory.getDefaultFactory();
                  pageContext = jspFactory.getPageContext(servlet, request, response, null, true, 8192, true);
                  ActionContext.getContext().put(ServletActionContext.PAGE_CONTEXT, pageContext);
                  usedJspFactory = true;
              }
              try {
                  super.doExecute(location, invocation);
              } finally {
                  if (usedJspFactory) {
                      jspFactory.releasePageContext(pageContext);
                  }
              }
          }
      
      }
      

      I created this, added it as a result-type then ran into bug: https://support.atlassian.com/browse/CWDSUP-6067 in theory this should allow me to use the Crowd styles and everything be happy.

      2) Not use the Crowd styles for my actions, or port them all to Freemarker. I can do this, but it is a bummer, and took me a long time to figure out how to handle this. The following code at the end of an execute method in an action can accomplish this (I wish this were in a guide, it would have saved me well over an hour of digging):

              ActionContext context = ActionContext.getContext();
              context.put("templateSuffix", "ftl");
      

      So just to conclude, the reason this is a major problem for a Crowd developer is there currently is NO way to distribute a .jar plugin that contains xwork actions and view templates that re-uses existing Crowd styles. Freemarker is broken for the reasons I listed above, the Velocity result also prints out a laundry list of exceptions if you try to use it, and there is no way for me to package and deploy JSP files.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              6c80a78e94f3 daviderickson
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: