Showing posts with label Ajax4JSF. Show all posts
Showing posts with label Ajax4JSF. Show all posts

Monday, February 15, 2010

An Ajax4JSF bug

The other day I had this exception:

15:16:47,296 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
 at org.ajax4jsf.org.w3c.tidy.Node.trimInitialSpace(Node.java:946)
 at org.ajax4jsf.org.w3c.tidy.Node.trimSpaces(Node.java:1012)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseInline.parse(ParserImpl.java:1125)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseTag(ParserImpl.java:203)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseRowGroup.parse(ParserImpl.java:2809)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseTag(ParserImpl.java:203)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseTableTag.parse(ParserImpl.java:2629)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseTag(ParserImpl.java:203)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseInline.parse(ParserImpl.java:1587)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseTag(ParserImpl.java:203)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseBody.parse(ParserImpl.java:978)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseTag(ParserImpl.java:203)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl$ParseHTML.parse(ParserImpl.java:486)
 at org.ajax4jsf.org.w3c.tidy.ParserImpl.parseDocument(ParserImpl.java:3409)
 at org.ajax4jsf.org.w3c.tidy.Tidy.parse(Tidy.java:363)
 at org.ajax4jsf.org.w3c.tidy.Tidy.parse(Tidy.java:261)
 at org.ajax4jsf.org.w3c.tidy.Tidy.parseDOM(Tidy.java:604)
 at org.ajax4jsf.webapp.tidy.TidyParser.parseHtmlByTidy(TidyParser.java:182)
 at org.ajax4jsf.webapp.tidy.TidyParser.parseHtml(TidyParser.java:265)
 at org.ajax4jsf.webapp.FilterServletResponseWrapper.parseContent(FilterServletResponseWrapper.java:594)
 at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:367)
 at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
 at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
 at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
 at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
 at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
 at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
 at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
 at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
 at java.lang.Thread.run(Unknown Source)

I was using JSF 1.2_13-b01-FCS with RichFaces 3.3.2.SR1. The problem turned out to be with the generated HTML content which Ajax4JSF was sending as a response. We were using a4j:repeat to generate a HTML table, and one row of this table was shown using an AJAX request. However, the default rendering behaviour of a4j:outputPanel is the using of some element (span or div, I don't remember which is the actual default), and the html tidy code above had problems with handling those elements between table rows. You just have to define layout="none" for the outputPanel, then it works fine.

The bug is since then reported: https://jira.jboss.org/jira/browse/AJSF-158

Friday, May 22, 2009

Using GWT and Ajax4jsf together

Recently I had to face a situation it's hard to speak about :) In a Seam+RichFaces based application we needed to develop a special component, which needs a large amount of client side JavaScript code. I decided to use GWT to develop this functionality. It's very simple to embed a GWT application supporting a JSF component to a page, especially if you have only one instance of the component on the page - you just include the compiled JS.

Everything seemed working fine until I tested it in Internet Explorer 6. In IE6, the GWT RPC calls just didn't succeed, the IE6 JavaScript error report said 'unhandled exception', in a meaningless line of JS code, of course. I found that it works fine if I don't have an a4j:form on my page. After a number of tries I found that the loading of the core JavaScript library of Ajax4Jsf already causes the problem, and then, looking through the code, I found a suspicious statement:

 XMLHttpRequest = function() {
  if (!_SARISSA_XMLHTTP_PROGID) {
   _SARISSA_XMLHTTP_PROGID = Sarissa.pickRecentProgID( [
     "Msxml2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0",
     "MSXML2.XMLHTTP", "Microsoft.XMLHTTP" ]);
  }
  return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
 };

And this turned out to be the problem indeed. Normally, the XMLHttpRequest variable is simply null. I didn't dare look through the GWT RPC implementation to investigate the problem further :) But at this point, we can already work the thing around.

So I introduced a 'beforeRequest' and 'afterRequest' JSNI methods in my GWT code to ensure that '$wnd.XMLHttpRequest' is null during the RPC call. This way, GWT RPC calls work fine, and the normal a4j functionality is still available in the page.