Java came up with "write once run everywhere".
How to do the trick with all the frameworks in the long term?
I wrote an application with JSF and richfaces a few years ago. Browsers have evolved and introduced new features and of course new bugs. Now the application still runs, and sometimes it shows javascript errors from the underlying libraries.
Do we really have to reimplement a finsihed application (no use cases to add) due to technical 'improvements' ?
EDIT: The application I mentioned was just an example. Same things easily happen if vendors change licenses. (Oracle could charge for a vm and open vm is not compatible with you application stack etc.)
Even if we believe "write once, run anywhere", it's not quite the same thing as eternal backward compatibility. Pragmatically, you must expect future versions of frameworks to change some things. Sometimes this will be the removal of what used to be guaranteed behavior (the worst kind of change), other times bugs in your code will go unnoticed until some future version of the library reveals that you were relying on an implementation detail that wasn't guaranteed. More rarely, your old code will reveal a novel bug in the latest version.
In an ideal world, we'd write code which relies only on guaranteed behavior, and guarantees would never be removed, and hence valid code would continue to work forever. Against that, it's hard to prove that your program is totally correct, and the language/framework/library developers make decisions about whether they can add the improvements they want to, while retaining perfect compatibility.
For compatibility to win the argument, the original API has to be strong enough and stable enough to survive without disruptive changes. If it isn't, then either non-compatible changes will be made, or else the API will be abandoned entirely. Either way, your program won't run any more unless you have an old version tucked away somewhere to run it on.
You ask how to do the trick - it requires either really good and somewhat lucky interface design in the first place to allow all the extensions you come up with later, or else a firm commitment and a "business case" (or non-business motive) to support the "old" version indefinitely. For example, Python 3 isn't compatible with Python 2, but Python 2 is still actively supported with updates, so old Python code still runs. C99 removes only a few features of C89, and if all else fails C89 compilers are still actively maintained. Browsers support a thousand and one old versions and non-standard quirks of HTML. I don't know how JSF and richfaces compare to those, or how much they output pages that rely on support for "old" (or quirky) HTML/CSS/Javascript behavior from the client.
So it can happen, at least for a while. But there are IE6 features which are no longer available in any browser that's safe to let out on the web (I guess you could run IE6 in a sandboxed VM, or on a machine you don't care about), so it's a question of what you depended on in the first place. Could it have been predicted that proprietary browser extensions would be dropped like a stone in future versions? Probably, but could those IE6 app-writers have achieved what they wanted to using proper standards available at the time? Not always. Even for those who didn't get involved with IE6, if your app falls into a similar trap, you're out of luck.