So it turns out that my hosting provider offers the ability to run your own Jabber server. Here’s what I did to get this working.
Continue reading Run your own Jabber server and federate with GTalk
So it turns out that my hosting provider offers the ability to run your own Jabber server. Here’s what I did to get this working.
Continue reading Run your own Jabber server and federate with GTalk
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\
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.
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 stuff:
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.
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() { } }
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?
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….