Websphere throws uncatchable exception
DWR pulls some neat tricks with backwards compatibility. We support Annotations, but can still be run from JDK 1.3. We support runtime type information from JDK 5 generics, and we can still run when java.util.logging is not present. Generally it is fairly easy – some reflection, some catching of UnsupportedClassVersionError and you’re good to go.
Except that Websphere has just thrown us a curveball. Get this:
try {
// Use a class that uses Annotations
...
}
catch (UnsupportedClassVersionError ex) {
// The VM does not support classes compiled with a JDK 5
// Don't print a stack trace, in fact, ignore it.
}
catch (Throwable ex) {
ex.printStackTrace();
}
This works just fine most place, however on Websphere 6 you get this:
java.lang.UnsupportedClassVersionError: org/directwebremoting/annotations/AnnotationsConfigurator (Unsupported major.minor version 49.0)
at java.lang.ClassLoader.defineClass0(Native Method)
It seems like the UnsupportedClassVersionError thrown by Websphere is loaded from a different classloader than the UnsupportedClassVersionError that we are trying to catch, hence the "catch Throwable" is hit rather than the "catch UnsupportedClassVersionError".
Is this explanation possible?
Where will this madness end? Is it possible to have more than one version of java.lang.Throwable in your VM, or more than one java.lang.Object – I have to assume not because there must be a special relationship between the VM and the system classloader. Anyone have any clue what is going on?
Introduction to Reverse Ajax
Jon Downes has written a great introduction to Reverse Ajax and how it works in DWR 2.0. From the article:
"The problem is that web servers can't easily contact web browsers. For one thing firewalls will get in the way, and even if they didn't, browsers only listen for answers to questions they've asked. So how is the web server to get the message through?
Answering this question is the essence of reverse Ajax. It is the means by which updates can be pushed from the server to the browser. Sure, techniques for doing this already exist and have cool names (see below), but Reverse Ajax ties them into a neat package and puts them more readily at the disposal of the developer."
The Reverse Ajax article is well worth a read.
$
There is a problem brewing for people that wish to use more than one Ajax library in the same page. It ought to be easy, but it's not...
Javascript has a problem - lack of language level namespacing / packaging. So if I write a web page that uses Javascript from 2 authors, both of whom defined a wibble() function, the result will probably be broken, and worse, since the second definition silently overwrites the first, the result will probably be silently broken. Rather than a compile/link error like in most languages, it will just blow up in your face at some stage.
According to Brendan Eich's Javascript talk, this problem is being fixed in Javascript2, but the Sun will be getting dim before all browsers support it enough that we can rely on it.
In the mean time the there is the very real danger of mid air collisions.
DWR has a $ function, copied from Prototype. So do Atlas and many other frameworks. Alex Russell says it is a very frequently requested feature for Dojo.
The $ function is the only function in DWR that isn't in an object based namespace. I'm not keen on it for this reason, but it is very useful: document.getElementById() is just such a mouthful.
But there is a problem:
- When Prototype changes their definition of $, what is everyone else supposed to do?
- What happens when Prototype's $ gets over written by a $ from another library without the new features?
- What happens if another library want to add some feature that Prototype doesn't pick up?
- What happens when to implementations of $ evolve in incompatible directions?
On one hand $ is a recipe for a mutual exclusion amongst Javascript libraries. It could mean that Prototype can't be used with anything but Script.aculo.us and other systems that go out of their way to evolve with it. Prototype's willingness to play with the "global scope" has caused bugs in DWR in the past that we have needed to provide work-arounds for, so it is a real problem.
On the other hand $ is very useful because you need to do it so often, and $ is something like 14 times less wearing on your keyboard than document.getElementById(). It's one of the sweetest bits of syntactical sugar there is for Javascript. The bad news is that the sugar is laced with another white powder that is both addictive and dangerous.
So here is my proposal:
Ajax library authors except Prototype should get together to define $ to mean basically document.getElementById() and nothing more. Each should do as DWR does and check for the existence of $ before defining it. Prototype on the other hand should not do the same check. Ever. Prototype should ensure that it's definition of $ is always a strict superset of the 'standard' definition.
DWR can be used with any version of Prototype because if Prototype gets declared first, it defines $ in it's superset form, and then as DWR is declared, it notices and does not alter the superset definition. If however DWR gets defined first, it will define $, however Prototype will overwrite the subset definition with it's superset definition.
My Talk at The Ajax Experience
A few people asked for my examples and slides from my talk at The Ajax Experience last week, so I've made it available for download.
The examples are done by "live-coding" and what you get is the start point. This means, a war file laid out properly with config files in the right places and a number of exampleX.html files and some Java files also with the outline tedium in the correct places, but the meat has been removed to a comment block at the bottom of the file.
During the talk I cut and paste the meat into the right places and talk about it as I ctrl+x, ctrl+v. It is trivial to work out where to put the code, and you can probably learn something by looking at what you are moving.
The slides are available as PowerPoint (534Kb) or PDF (200Kb).
The examples are available as a .zip file (259Kb).
The slides contain a fair bit more than I actually presented. I like going in with more than I need in case I talk too quickly, or in case someone asks a question that I wasn't planning to cover.
HTTP-301 for RSS
RSS feeds are way too static. A blogger can’t easily change feed URL without the co-operation of their entire subscriber base.
2 examples:
Robert Scoble changed his feed URL, and six months later his subscriber count is under half of his original subscriber count (according to Bloglines). I'm sure Robert would have loved to have automatically moved the thousands of subscribers to his new blog automatically, and I would prefer not to need to re-subscribe.
Russell Beattie decided to stop blogging, but his several thousand subscribers couldn't be bothered to unsubscribe - and why would they; he might start blogging again, and anyway it's only a hassle to unsubscribe. However for Russell, this means his server gets perpetually swamped by hundreds of update checks for an update that will probably never happen.
The reality of the situation is that you can't change your feed URL without a huge effort. How long does it take one person to change the feed URL for one blog? Maybe 30 secs or less if you are quick, but the average is probably longer and it depends a lot on how simple your aggregator it. So it's easy to understand why people don't bother, and that's if they noticed the "re-subscribe over there" message in the first place.
I'm sure Robert would like to aggregate his 2 subscriber lists. I'm sure Russell would really quite like to point his subscribers at a holding blog hosted somewhere else so he doesn't get the traffic and maybe that even gives him the option to start again at a later date.
These problems make sites like Feedburner both very valuable and a "sell your soul" type service. But what happens if Feedburner gets greedy? Maybe the Feedburner servers get "overloaded" and it takes a long time for your updates to get propagated, and maybe they introduce a premium service to help people get the word out fast. Would you want to pay? If your feed URL is very hard to change don't you want to control it yourself?
These problems are compounded by the how ill defined your feed URL actually is. The RSS feed I’d prefer people to use for my blog is http://getahead.ltd.uk/blog/joe/rss.xml but you can also get it via http://www.getahead.ltd.uk/blog/joe/rss.xml or http://getahead.ltd.uk/blog/joe/atom.xml or http://www.getahead.ltd.uk/blog/joe/atom.xml and all have subscribers at Bloglines.
We need a way to say, "this is not the feed you are looking for", a bit like an HTTP-301, but one that you can create simply by editing the text of a blog.
We need a micro-format for blog redirecting.
This new micro-format must:
- Be readable by the worlds feed aggregators.
- Allow bloggers to point subscribers to a new feed URL.
- Be simple enough that it can be used by bloggers with a limited ability to edit the text of their blog.
- Make sense in a HTTP form as well as an RSS form. This rules out (this and the last rule out HTTP-301)
It would be also be nice if:
- The honchos at MySpace couldn't block it easily.
- It gave people that have had their blogs hacked a chance to change their minds.
So how about this for a solution; the micro-format looks like this:
<p>autoresubscribe using <a href="url">url</a></p>
In fact we could probably dispense with the <p></p> elements to make life simple.
The rule could be that the "autoresubscribe" blog entry must remain on in the RSS feed of the blog for 30 days or more to become permanent. If it is removed before then, it is assumed that the blog was tampered with and the redirect is cancelled.
There is a slight worry about false positives. What happens if the text above matches somewhere else by mistake? As far as I can tell, so far the web it totally devoid of any mentions of the phrase "autoresubscribe using", so if we combine that with a requirement to have a url in a link to that url, I think we should be safe. Even this blog entry describing the micro-format with examples shouldn't match.
There is the issue of internationalization; the proposed solution is great for the English speaking world but not so good for non-English blogs. On the other hand "autoresubscribe" isn't exactly a real English word in the first place. Maybe the spec would define a number of languages in which this could be written. Probably support for every one of the worlds 300 trillion languages is over the top, and we could limit ourselves to the top few. It is only 2 words after all. Or am I being too colonialist?
All we need to make this work is the support of all the world's feed-readers. Surely that's a simple problem?
Right?
DWR support in MyEclipse
There is a thread going on in the MyEclipse forums about support for DWR in MyEclipse version 5.
If you are into DWR and MyEclipse it's well worth heading over and commenting.
DWR 2.0 milestone 2 lets you write Javascript in Java
Milestone 1 delivered Reverse Ajax and other goodies. Milestone 2 adds Annotations, Reverse Ajax using Jetty Continuations and the ability to write your Javascript in Java and more.
Writing your Javascript in Java is particularly cool. Rather than explain it twice, you really need to read the release notes for more details.
JSR: Continuations
We need a JSR for Continuations.
I've been working with Greg Wilkins to allow Ajax in DWR to work properly with Jetty Continuations. But Jetty Continuations are just one of a number of implementations of a great idea. We need a JSR so that I don't have to do the same job 20 times:
What is a Continuation?
The best short description I've seen is one from Paul Graham's On Lisp that Brian McCallister referred to.
A continuation is a program frozen in action: a single functional object containing the state of a computation. When the object is evaluated, the stored computation is restarted where it left off. In solving certain types of problems it can be a great help to be able to save the state of a program and restart it later. In multiprocessing, for example, a continuation conveniently represents a suspended process. In nondeterministic search programs, a continuation can represent a node in the search tree.
Brian's whole Continuation blog entry is well worth a read. Sam Ruby has a great article on the subject, or there is also an IBM DeveloperWorks article which goes into a bit more depth or a Wikipedia article.
Implementations
- Continuations are in Rife and this code is used by WebWork.
- Continuations are in JavaFlow. Although this is still in the sand-box.
- Continuations are in Cocoon and the vast eco-system behind that.
- Continuations are in Jetty and DWR has tweaks for this written by Greg Wilkins.
- I've heard that BEA are building continuations into Weblogic too. Can anyone confirm this?
It looks like James Strachan is toying with the idea at Codehaus, but not creating anything.- Continuations are in BPMScript "BPM is used to attempt to automate these business processes".
That's 6 implementations, and I don't want DWR to have to have hacks for them all.
Conference Season and Conference Season Announcement Season
So Conference Season is starting and with it comes Conference Season Announcement Season where everyone feels the need to announce where they are speaking in the next few months.
All this is very ____________ (please fill in your chosen adjective here), but in true sheep mode, I'll follow the herd:
May 10-12: The Ajax Experience: I'm doing a talk on DWR, including some of the new 2.0 stuff. Live coding etc. Bram Smeets is also going to be talking about DWR and Spring. I'm really looking forward to the Ajax Experience.
May 16-19: JavaOne: I'm in the Smackdown for AJAX Programming Models and Frameworks. I'd like to be able to tell you what to expect. But that would require me to know myself. Maybe we'll all have a big Ajax love-in or maybe we'll all discover that the other guy's are clueless dweebs fit only for tarring and sending to /dev/null.
For a long time there was only me and Greg Murray on the panel. It's good to see that there will be some other people to discuss Ajax with.
June 21-23: TSSJS-Europe: I'm first up to talk about DWR. If you come to my talk then you'll miss Geert Bevin talking about Rife, and Ted Neward talking about TBD. TBD sounds interesting - maybe he's got a new web framework ;-)
Now if I was a real geek I'd have all of this available in an iCal feed from Google Calendar. Maybe I'll work on that. Maybe.
DWR in French
DWR has some great documentation on the website and there is a growing list of books that include chapters on DWR - but it's mostly in English. Julien Dubois (DWR committer) has recently written a French book primarily about Spring - it includes a section on DWR. The great news is that this chapter is one of the free download chapters. Get the PDF.
Spring par la Practique is available now.
DWR possède une excellente documentation, et de plus en plus de livres incluent des chapitres traitant de DWR - mais tout cela est principalement en Anglais. Julien Dubois (commiteur DWR) vient d'écrire un livre en Français sur Spring, lequel inclut un chapitre sur DWR. La bonne nouvelle est que ce chapitre fait partie de ceux téléchargeables gratuitement. Téléchargez le PDF.
Spring par la pratique est disponible maintenant.
What other non-English DWR resources are there out there?