Category Archives: java

Tomcat XML error

Getting this error in Tomcat?

java.lang.NoSuchMethodError: org.w3c.dom.Node.getTextContent()Ljava/lang/String;

There’s a good chance you installed Tomcat with the JDK 1.4 Compatibility package and are now running under JDK 5.

To fix it, delete xercesImpl.jar, xml-apis.jar and xalan.jar from $CATALINA_HOME\common\endorsed\

My problem with Guice

I went to a presentation at my local Java User’s Group last Monday on Guice. I’m a long time Spring user (and fan), so I was interested to see what benefits it had over Spring.

I came away with the impression that Guice looks pretty interesting, but its main benefit over Spring is the lack of XML. That’s okay I guess (although I personally think the case against XML is often overstated). I certainly wouldn’t be opposed to using Guice in a project based on what I saw – except for one thing….

My big issue with Guice is the fact that it appears to be invasive. Based on the presentation I saw it seemed that you need to instrument your code with @Inject annotation for the dependency resolver to provide that dependency. That’s fine in your application code, but it means wrappers seem to be required for third party libraries. However, there are some hints from the documentation that this isn’t the case (‘Observe the Java type and the optional “binding annotation” of the element to be injected‘). OTOH, ‘sometimes you can’t use annotations, and you need to manually wire up an object (a 3rd party component for example). When this comes up, you write a custom provider‘ (See http://code.google.com/p/google-guice/wiki/SpringComparison). That’s kind of confusing, and something I’ll need to investigate more.

All in all – an interesting option, and one that certainly replaces PicoContainer as the best code-centric dependency injection container.

DWR Callback closures inside loops

I’ve been doing a fair bit of Javascript lately. Like anytime I learn a new language I look back at code I wrote a week ago and thing OMG… what was I thinking!?

One useful thing I learnt today was how to use the DWR closure callback pattern inside a loop.

My original code looked like this:


var taggedLinks = $$(".taggedlink");

for(var i=0; i < taggedlinks.length; i++) {
	RatingApi.getRating(taggedLinks[i].href, {
		callback: function(data) {
			displayRating(data, taggedLinks[i]);
		}
	});
}

Where RatingApi.getRating(..) is a DWR AJAX call. It’s fairly clear what the problem is: the displayRating function is called when RatingApi.getRating returns. Obviously the value of i will be not what was expected.

The solution looks like this (thanks Ben!):


var taggedLinks = $$(".taggedlink");

for(var i=0; i < taggedlinks.length; i++) {
	var remoteCall = {
		index : i,
		callback: function(data) {
			displayRating(data, taggedLinks[this.index]);
		}
	};	

	RatingApi.getRating(taggedLinks[i].href, remoteCall);
}

Random Observations on developer stuff

Random stuff:

  1. There's huge demand for (good) Java programmers. (Live in Adelaide, want a job & know Java? Contact me… Also, I'm still looking for an XUL person.)
  2. Javascript might be the next big language, and while everyone claims they can program in Javascript what they mean is that they know how to pop-up an alert box in a browser window. That isn't programming! (Live in Adelaide and know AJAX and possible a bit of Java? Contact me….)
  3. Spring is good.
  4. Doing estimates for a project when there are no requirements is difficult.
  5. Doing estimates for a (different) project when the functionality, resources and timeline are all fixed is very difficult.
  6. Social networking.. there's just too much to write on that topic.

ROME 0.9 released

Dave has done some great work getting the ROME 0.9 release out. There's also a new release of the ROME Fetcher.

I did an interesting fix for an ROME XML based security vulnerability in this release. I plan to blog about it in some depth later, but for the moment it's fair to say that the problem is somewhat obscure, but you probably should upgrade if you care about security. I also submitted patches to fix the same problem in Jakarta FeedParser, and Kevin's Tailrank version of FeedParser. A quick code inspection indicated that Informa is probably vulnerable, too, but I haven't got around to doing a patch for that.

Nelson (who pointed this out to us) has said about 3/4 of the XML applications he's encounted are vulnerable to this problem. After the lengths I had to go to fix it I'm not surprised – insecure by design is how I'd describe the XML APIs.

Switched to Feedburner

I've switched my feeds at my BadMagicNumber blog to be published via FeedBurner. There should be no disruption to your normal programming, although I think some aggregators will show some non-new items as new.

I switched the feeds over using a simple Servlet Filter. If anyone wants to do the same, here's the code. This works for blojsom, but you might need to modify it slightly for your own setup.


public class FeedBurnerRedirectFilter implements Filter {
	private String redirectURL;
	
	public void init(FilterConfig config) throws ServletException {
		redirectURL = config.getInitParameter("redirectURL");		
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
						throws IOException, ServletException {
		String flavor = request.getParameter("flavor"); 
		
		if ("atom".equals(flavor) || "rss".equals(flavor) 
				|| "rss2".equals(flavor) || "rdf".equals(flavor) ) {			
			HttpServletRequest httpRequest = (HttpServletRequest) request;			
			HttpServletResponse httpResponse = (HttpServletResponse) response;
			
			String userAgent = httpRequest.getHeader("User-Agent");
			if (userAgent != null && userAgent.indexOf("FeedBurner") < 0) {
				/// redirect if not feedburner
				httpResponse.sendRedirect(redirectURL);
				return;				
			}
			
		}		
		chain.doFilter(request, response);		
	}

	public void destroy() {
		
	}
}

Using XPath on real-world HTML documents

The article on the Server Side about Web-Harvest reminded me on one of my favourite things: using XPath to extract data from HTML documents.

Obviously, XPath won't work normall on most real-world webpages, because they aren't valid XML. However, the magic of TagSoup gives you a SAX-parser that will work on ugly HTML. You can then use XPath against that SAX stream.

Here's the magic innvocation to make TagSoup, XOM and XPath all work together:

XMLReader tagsoup = XMLReaderFactory.createXMLReader("org.ccil.cowan.tagsoup.Parser");
tagsoup.setFeature("http://xml.org/sax/features/namespace-prefixes",true);
Builder bob = new Builder(tagsoup);
Document doc = bob.build(url);

which then allows you to do things like:

XPathContext context = new XPathContext("html", "http://www.w3.org/1999/xhtml");
Nodes table = doc.query("//html:table[@class='forumline']", context);

Cool, hu?

Develop AJAX applications in Java (just Java)

Google Web Toolkit (GWT) is a Java development framework that lets you escape the matrix of technologies that make writing AJAX applications so difficult and error prone. With GWT, you can develop and debug AJAX applications in the Java language using the Java development tools of your choice. When you deploy your application to production, the GWT compiler to translates your Java application to browser-compliant JavaScript and HTML

From Google Web Toolkit – product overview

Wow. And it looks like it actually works….