So the latest buzz is all about the Time Magazine Person of the Year for 2006... instead of narrowing down the field, Time decided to pick everybody.
Yep... You are Time's Person of the Year. Just like in The Big Lebowski.
I understand their motives... blogs and sites like YouTube have really turned the world on its head... and have really shocked those in the media industry who believed themselves to be the gatekeeprs of information. Each new internet innovation reduces their power more and more.
Well, then why not make the YouTube guys the Persons of the Year? Or maybe the webroots activists that influenced the 2006 election by capturing Macaca moments? Maybe throw in some Ze Frank?
Come on, Time! Pick a horse!
Anyway, Andy MacMillan had an awesome idea last night... since we are all now considered Time Magazine's Person of the Year, we should all update our resumes. We should place it on our list of accomplishments on our blogs, our MySpace pages, and all our online profiles. I mean, Person of the Year 2006 is a big deal, right? You should be proud!
I hope to see many many more by the end of next week...
Well this sucks... Google has quietly decided to deprecate their SOAP API. Web developers used to be able to use the SOAP API to run a Google search, then display the results in their own page. They were also able to re-order the results in case that web site wanted to highlight specific links.
Google is instead pushing people to their AJAX API for search... which has fewer features and a more restrictive license.
Don't be evil!
I'm confused why they didn't push their GData API... which is a pretty 'REST-ful' API. Apparently Google cares not for SOAP nor REST, and prefers non-standard AJAX and Mashup APIs instead. I'm curious where this road will lead... I hope its somewhere good.
The article above had one very interesting quote from Tim O'Reilly:
On the other hand, SOAP has always been a political football shaped by big companies who were seeking to use it to turn web services back into a controllable software stack. I remember the first web services summit we did, where a Microsoft developer who I won't name admitted that SOAP was made so complex partly because "we want our tools to read it, not people."
Grrr... stupid Microsoft and W3C. Ruining SOAP so they can do proprietary RPC with their magic little tools.
Now everybody is saying good riddance because XML-RPC is sooooo much easier anyway. Totally true, but completely missing the point. RPC in complex systems generates nothing but slow, inflexible, brittle code.
If you have to worry about methods, objects, or resources, you lose. That's too low of a level. Remote APIs need to be much more abstract... otherwise there are too many things that can go wrong.
I blogged previously about the advantages of offshore wind farms. The two obvious benefits are that the winds are more consistent over the ocean, the windmills are less visible, and there is less damage to migrating birds.
When in full production, it should be able to supply electricity to almost a million homes, using just the power of the wind. Very exciting!
The array takes up about 90 square miles. That sounded like a lot to me... and its important to remember that it will only supply 1% of the energy needs of the country at full capacity.
If these numbers scale, you would need a 9000 square mile array of wind turbines to supply energy to the entire country... which is one tenth of the size of the entire UK. I'm not sure if they can do that without placing some generators into international waters...
Clearly, it will be difficult to supply energy to an entire country using just wind power... but hopefully it will tide us over until we get that fusion problem nailed!
Both times it gave me the willies...
It looks like great technology: online web collaboration based on HTML and a bit of Java... But I've always been a wee bit suspicious of hosting important information on somebody else's server. I'm suspicious about using Google to run my Patent Search for the same reason.
However, Yugma is a Minnesota company, and they did mention that you can host your collaboration on a non-Yugma server for added security... so I decided to at least try it before I judged too harshly.
So, I try to start a 'session,' and it launched a signed Java applet. I checked the signature, and it looked OK... but then it decided to install itself on my computer without notifying me or asking.
I know that's the best way to get performance out of applets, still it seemed a bit rude. Plus, it didn't come with an uninstaller! Doubly rude!
Warning bells going off like crazy, I decided to not use Yugma. I scrubbed all traces of it from my computer...
Maybe Beta 2 will be less evil... but I'm not gonna hold my breath.
In honor of this Monday morning, here's a little pick-me-up:
Now have nightmares all week...
So I was surfing Amazon to do some xmas shopping today, and couldn't help myself from checking up on my book. I have a screen-scraper that tracks the sales rank, but I still like to check it manually once in a while...
Anyway, for some odd reason, Amazon decided to pair it with the Interwoven book on Team Site:
Odd... it probably would be better paired with a book on HTML, CSS, or Information Architecture... instead of a competitive product!
In a way it makes sense. If you are preparing to purchase a CMS, it makes sense to buy both books even if you're only going to use one, so you can compare, and choose which one to buy.
... and then decide upon Stellent ;)
After a glib commenter suggested I do some more reading about REST before I bash it so much, I took his advice. I read, and read, and read... Did my opinion change?
Not so much.
A lot of the debate in the REST/SOAP camp seems a little odd to me... the REST folks complain about SOAP being complex and weird... but that's not SOAP's fault. That's the fault of Microsoft and the W3C for trying to complicate matters beyond necessity. If you don't like it, don't use it.
Then there are the Talmudic debates about using POST versus PUT, which HTTP error code to use, or even encouraging Remote Procedure Calls (RPC)... those are mostly silly.
So, I'm going to add three more big reasons why REST gives me the willies:
Resources Versus Services
A web API should be somewhat analogous to a graphical interface: event driven. I click a button, and it does a thing. What does it do? I don't care... as long as its exactly what I want, I'm happy.
Users are so fun!
The problem is that step 1 of a REST API means you have to find the resources you wish to modify, and then call the service. What if I don't know what resource I want to modify? What if I don't care if the resource is a uk-customer or a european-prospect, I just want to record some data about a dude I met in London?
Remote APIs should focus on the action, not the back-end implementation. Otherwise you'll be tempted to use RPC, which is the exact opposite of good SOA.
If you force the user of the remote API to know what resource it is, then you lose some flexibility. What if you want the back-end system to decide what the resource is? Maybe it should be different based on the context of the request, and the user's credentials? What if you upgrade your system, and change the back-end implementation to use different resource names?
To avoid problems, you must force yourself to push more and more abstract resource names to the front end... which means you lose a lot of the value of named resources. The ultimate endpoint is when you have one resource named resource that takes an action parameter... at which point you're pretty much just doing SOAP.
Implied Resource Hierarchy/Taxonomy
If you have a small system, using named resources may work just fine. And in that case, REST makes it easy to know what services work for what resources. I myself am a fan of human-readable documentation, but to each his own.
However... this sort of implied hierarchy also gives me the willies.
The web is most definitely not hierarchical. Every attempt I've seen to create a taxonomy for it has failed. Even single taxonomies of intranets are unworkable. Look at Amazon.com for example. Every book is in multiple taxonomies, to aid in how people choose to browse for their options.
Extending this to REST, what if you want one service to update 10 resources simultaneously? What if the name and type of these resources changes on the fly? What if you're only allowed to choose 8 of the resources, the other 2 determined for you by the back-end system? What is the clear an unambiguous REST URL for that?
If its service-oriented, you'd call a service named FunkyActionOnTheseResources, then pass in ten (or eight) resource IDs as XML nodes. Done and done.
No taxonomy, no worries. But of course, you'll need to document them better... but that's always helpful.
HTTP Is Kind Of Broken
The REST people ask one interesting question: why does SOAP tunnel through HTTP, when HTTP is fine as it is? Well, because HTTP is not fine as it is. It is broken in lots of little ways which may seem minor, but can cause huge problems. You do lose something with tunneling, such as caching in browsers or reverse-proxies... but you gain control. And obviously, there is more than one way to implement a cache.
My personal big gripe is that there is a HTTP header for the encoding of the content, but not the encoding of the header! If I have a Japanese user name in the HTTP header, how do I know if its encoded with utf8, utf16 or shift_jis? I don't! You literally have to cross your fingers and pray. When it comes to logins, being helpful is a security hole.
And what happens if your browser gets a 404 error message? Does it display the actual response from the web site, or one of those 'friendly error pages' from Microsoft? What if your intranet has a helpful policy that sends back an internal error page in the event of a 404? And who knows what fun will be had in the future...
I'm sorry, you just can't trust HTTP to do what you want. Even if its in the spec, that doesn't mean its used by the applications you rely on.
For maximum compatibility in the most number of environments, some data must be placed outside of HTTP headers, period. If you build a system that relies on people always following the spec, you will soon know misery.
Not The End
There are good ideas about simplicity in the REST camp... I feel that those ideas should be brought into SOAP, instead of abandoning it.
We should abandon WSDLs, data binding, and strong typing in SOAP. The only reason to have those is if you are trying to tunnel RPC through SOAP... RPC is already a bad idea, don't make it worse by forcing people to use XML to describe a binary data object!
Allowing SOAP responses through GET is a good idea, and its one Stellent implemented 3 years ago. It wasn't in the spec, but it Just Made Sense®, so we did it.
Who knows what will happen to SOAP... but if you have technology that can adapt faster than everybody else, you will win.
Informit posted an interesting article on Google keyword hacks. By typing the right search terms into Google, you can get it to give you the weather, convert meters to inches, or even track a UPS package.
Try some of the following Google searches, and observe the first item:
- 2 + 3
- speed of light
- 1 meter in inches
- what is defenestrate
- president germany
- population San Francisco
- birthplace Mark Twain
- weather Minneapolis
- msp airport
- John Smith Minneapolis MN
- movies Casino Royale
- Tom Waits
- What is the answer to life, the universe, and everything?
At this rate, our brains will become obsolete by 2013.
I found an article on Luke Francl's blog about one of those esoteric debates between SOAP and REST for web based APIs. It was between a REST fanboy and a fictitious EBay Architect. It is supposed to be a nine part series, but has stalled a month ago on issue #2.
The REST fanboy was schooling a fictitious EBay architect about why the SOAP-based EBay API sucks... it was fairly one-sided, and had multiple errors and omissions.
Suddenly... a real EBay architect decided to challenge the fanboy on his blog. And, in a nice way, dared the REST fanboy to stop shadowboxing, and submit his questions to a real developer who can defend EBay's SOAP-based API.
Nerd fight! Fighting nerds! We don't use guns, we use words!
I read all of the blog posts, and am still fascinated about how people just don't get what an SOA really is... One commenter summed it up nicely:
SOA != SOAP
Back to the original rant... I am generally not a fan of REST for multiple reasons, including:
- It treats file uploads like second hand citizens. If it ain't XML, REST doesn't know what to do with it. SOAP on the other hand, handles multiple file streaming formats nicely.
- It fundamentally breaks its own philosophy about portable URLs by using the same URL for viewing and adding items. It hides the details of what happens in HTTP black magic. No good.
- It continues to cram the antiquated and counterproductive object model at us for network applications. We tried that three times, it doesn't work! Services are the way to go, and SOAP is a natural choice (although neither necessary nor sufficient) for SOA.
In that second item, I'm referring to the difference between REST and frameworks like Ruby On Rails and Django. In a Rails/Django application, if you enter the URL http://host/customer/, you will see a list of customer entries. If you change the URL to http://host/customer/add/, it will usually show you a web form where you can add new customer entries... although you can modify that if you want.
Clean. Simple. Extensible. Logical. You can easily map that URI to a SOAP service name and call it a day (but nobody does).
However, in REST you are supposed to use the URL http://host/customer/ for both the display of a customer, and for modification. The magic is that a HTTP GET method will return the list, whereas a HTTP POST method will allow modification.
News flash to REST fanboys: there are probably more than two things that you would like to do with a customer besides viewing and modifying... what if you want their purchase history? How about a contact form? How about a list of customers who canceled their subscription? You need something extensible; something that can break rigid standards in favor of solving business problems.
Sure, you can cram that flexibility into REST, but then what's the point of the entire REST analogy? We are always hearing about how the HTTP methods POST, GET, PUT, and DELETE map so nicely to the Create, Read, Update, and Delete database model. If you abandon that, what else is left?
Another news flash: a web application should be more than a database front-end. If I'm wrong, we can scrap every web app in the world and just use phpMyAdmin.
Plus, all of that talk about SOAP not being scalable is just plain marketing FUD. There are a billion ways to make web applications faster and more scalable, and it usually involves some kind of federation, combined with caching.
Thanks for reading... I had to get that off my chest.
I'm not making this up...
Some of their analysis included:
Articles like, "The Technique of Concealing Files from View" and "How to Protect Your Files, Even if Your Device was Penetrated," were written for the intermediate to advanced user, and describe a variety of methods and software that provide security. Links to download referenced software, such as the VMware virtual machine, and key generators to unlock features are also given by the editors. Another writer discusses PGP (Pretty Good Privacy) software and determines that its encryption is not adequate for the needs of the Mujahideen.
So... the jihadists have determined that encryption is not sufficient to secure their data. I wonder how long it will take Wall Street to figure that out! ;)
Seriously, when stuff like this hits the internet, it makes me wonder how much longer wars -- even little wars -- can be used to accomplish a lasting goal.
It makes me think that the writers of The Fifth Dicsipline are right... the only way for any group to survive is if it learns faster than opposing groups.
I'm reading into it a bit... but basically any culture that can embrace the wild and free marketplace of ideas on the internet will thrive... even if the immediate result is unrest, power shifts, or the threat of "foreign ideas" befouling the "purity" of the existing group. This applies equally well to countries, cultures, corporations, and religions.
Any group so dogmatic that they refuse to learn from anything unless it was written 2000 years ago, will likely find themselves left behind.
Isn't it always the case... the first sick day I need in a year and a half... and guess what? I'm unemployed!
Oh well... Herbal tea is much cheaper than a doctor's visit. I got some Gypsy Cold Care and some Elderberry Ecinacia. No clue if they help, but I'm feeling much better.
Plus I'm a little weary of the anti-virals that the doctors use for the flu. They don't seem to work on me. They make my arm go numb for a whole day. The first time I got a flu shot, I caught 2 flus within a month. The next time, I caught a flu within a week!
I don't know if its full-blown quackery, or somebody sneezed on the syringe... But I'll wait till they get the kinks out of the system before I do it again!
Yes, the rumors are true... I have decided to resign from my job as a Stellent developer, and try my luck in the big bad world as an independent consultant! Today, December 1st 2006, is my last day.
This change has been coming for some time... I've had the run-my-own-business itch for years. I've talked about it at length with my boss and co-workers. And now, with Stellent being purchased by Oracle, the timing couldn't be better.
It feels great to be a part of something bigger than myself... like helping to create a product as uniquely innovative as the Stellent Content Server. Down in development, we were contrarians about everything. We used Java when nobody else would. We had a web based interface before most people had email. We had a data-driven framework for quickly adding features, while others used ivory tower OOP that was impossible to customize. We had a service-oriented architecture (SOA) seven years before there was even a word for it! Most of that was Sam White's vision... we were just the lucky ones who extended it to include our vision.
I can go on and on and on about newer features that we did right... but based on history, nobody will believe that it was the right design for another five years! Plus, Oracle would frown on me blabbing too much...
My favorite part is that whenever somebody said we should re-write the entire product to leverage trendy new buzzword X, we would demand a complete answer to one simple question: why? Not because we didn't want to write the code, but because we wanted to nail it: do it in a way that Just Made Sense.
We were pulled in every direction and asked to do everything: XML, XSLT, EJB, Application Servers, Portal Servers, JSP, ASP, SOAP, you name it. Some were good ideas, some were natural extensions to the product; others were an awkward fit. But we refused to ever jump on any bandwagon, or drink anybody's kool-aid... and that defiance has made all the difference.
Luckily, since we were an SOA through-and-through, we could create a loosly-coupled integration with just about anything... which helped when people demanded that we integrate with just about everything!
I know I'm leaving Stellent in good hands with Oracle. Unlike a lot of big companies, these guys really seem to get it. They know a lot, but more importantly, they know what they don't know.
For example, we have been considered leaders in content management infrastructure for years, despite being actively targeted by huge companies that usually crush the competition: IBM, Microsoft, EMC, you name it.
I feel Oracle understands that Stellent hit upon a formula that was remarkable, and I think they're really curious to know the recipe for our secret sauce. How did we constantly school the big boys, despite having less than a tenth as many developers!? He he he...
In the last lines of the last chapter of my Stellent book, I talk about what the future of Stellent could be. Little did I know, that six months later I have to rewrite the damn thing. I'll probably have to type more than just
Anyway, the final words in my book are these:
Regardless of what the future holds, you can be sure that the Stellent Content Server can rise to the challenge. Stellent has the most flexible ECM system available. Its Java engine allows it to run on virtually any platform. Its data-driven service-oriented architecture allows it to quickly integrate with any remote repository or implement practically any new specification.
In short, bring it on.
I spoke those words with total confidence when Stellent was one thousand times smaller than the competition.
And now? Well, lets just say, those guys are sooooo toast...
OK, you mean Amazon turkeys, I'm on to you!
I suddently noticed a lot of access denied messages in my error logs. Some one or some thing has been trying to edit my blog posts... luckily I keep my security patches up to date.
Anyway, I recorded the IP addresses, and used ARIS WHOIS to trace back their IP addresses, and guess what? Its Amazon.com.
I don't know if its a sysadmin who was mad that I posted info on security holes at Amazon.com (which they fixed nicely)... a hacker who is disguising their IP address... or a misconfigured web spider. It could be a taunt, an accident, or malice.
In any event, I'll be contacting them and my ISP in the morning. I hope I can schmooze a free book out of this...
This is the funniest Daily WTF? I've seen thus far: No Line Breaks? Aaaaaaaaaaaa!
I laughed for quite a while, then cried. Then laughed again. You'll need to know HTML to get the joke.
OK, I should really go home now...
For those of you who don't know, there was a pretty serious accident in downtown Bellevue, Washington last week... Bellevue is a cute little suburb of Seattle that thinks its a city.
For some reason, one of those huge construction cranes collapsed, and took out a small building. They are still investigating why.
The damage could have been a lot worse... it occurred at 7:45 PM, after most businesses were closed, and few cars were on the street.
Several buildings were spared, including one of the offices of Stellent's parent-company-to-be: Oracle. If the wind had been blowing from a slightly different direction, the Oracle building would have been severely damaged... Check out a Google map of the distance between Oracle, and the destroyed building.
Provided this acquisition goes off without a hitch, the Stellent folks out in the Redmond office will probably move into that lucky Oracle building. We lease the current office from Microsoft, and Oracle is understandably not enthused about that.
The only fatality was Matthew Ammon, my sympathies to his family... he was a patent attorney who was recently hired by Microsoft.
My conspiracy nut friends will probably raise an eyebrow over that one.
I'll have to confer with my pagan friend and/or Nancy Reagan as to whether this is a good or ill omen. Death is usually an ill omen, unless it helps people appreciate our short lives a little more. I'm hoping for the latter.
In that spirit, allow me to wish everybody a happy Thanksgiving!
Enjoy your crazy family and dry turkey. Enjoy the cacophony and chaos. Eat, drink, and be merry! For tomorrow... well... you never know.
See ya Monday!
UPDATE: Brian Cheyne corrected me in that in my map, I selected the wrong Oracle building. The one they will probably be moving into is even closer to the crash site... a mere 250 feet away. You can even see the crane on the Google map: its that white line just to the left of the green mark.
Yikes, there's a lot of them... Like about sixty.
Why Yahoo? Well, its released under the über-friendly BSD License. No worries about being sued because your web application contains GPL code. Also, Yahoo has tons of samples and documentation online. Plus these libraries are being used heavily by a major web company, so it won't go away any time soon. Its not as fully-features as some other libraries, but it has most of what you need... and they seem to be adding more all the time.
They need more specialized instances in the Container family of objects... but overall its easy to use. They even have accessibility tips for each design pattern.
I just came across a great site, The Daily WTF, which is a tribute to the mind-bogglingly bizarre things that happen in the software industry.
The site is loaded with stories of incompetent developers, bizarre consultants, and clueless pointy-haired bosses. A few times a week they post source code from production systems written by "professionals" that are so very wrong it hurts my brain.
One of my favorite code snippets was this one:
public boolean aMethod(Object anObject)
/* some really bad code */
catch (Exception e)
Holy frijoles, Batman... A recursive error handler... And remember, this was code found on a production environment.
Another story was a great tale of Microsoft Terminal Services gone wild. Some poor developer had to use terminal services to connect to a remote server and run a batch process for data entry. The batch process ran for seven hours... but unfortunately for "security reasons" their network would drop the connection if there was no activity for 15 minutes. If that happened, then the batch process would crash, and they'd have to start it all over!
He had no success getting IT to change the policy, or change the batch process... and he and was going nuts trying to wiggle the mouse every 15 minutes.
After several days, his manager envisioned a solution that can only be described as extreme out-of-the box thinking. He brought in his child's Fisher Price Vibrating Rocking Chair, and attached it to the mouse. The small vibrations caused the mouse to move, and tricked their security policy into thinking there was constant activity.
To this day, the Fisher Price Rocking Chair is a vital component to their enterprise-level automation process.
Wow. Just... wow.
Good news! According to the New York Times, there has been a net increase in forested land in many of the worlds largest countries.
Specifically, over the past 15 years 22 of the 50 countries with the most forests have increased the amount of forested land. Turkey, India, and China have joined with Japan, the US, and Europe when it comes to forest conservation.
Of course, there are concerns... countries like Brazil and Indonesia are still cutting forests at an alarming rate, so the overall global trend is still negative.
Plus the data is not 100% reliable. Some of it was provided by government agencies, who might not be the most impartial of judges... Other data was from areal photographs, which might overestimate the number of trees in a lush canopy.
I'm optimistic... not simply because of policy changes in India and China, but also because we have new tools to help monitor the situation. Such as Google Earth.
By using Google Earth and hand-held GPS systems, researchers are arming Amazon natives with powerful tools to monitor their land. With careful observation of satellite images, the natives can discover miners or loggers who are operating illegally on their land. This will hopefully help turn the tide...
Naturally, Google doesn't have all the historical data that researchers would need to discover trends, but it certainly contains a wealth of useful information... and their areal data can be verified with spot-checks on the ground to calibrate their estimates.
The Amazonian natives are only the latest group to use Google Earth for research purposes. Archeologists have been using it for months to discover ancient cities, buried right in their backyard. I'd wager that 2007 will be filled with new finds that may force us to rewrite some of the history books.
What's next for Google Earth? X-Ray cameras in space? Maybe then I could Google where I left my keys...
After reading some odd posts, accusations, and recriminations on Digg, I decided to take a peek at how integers work in Java 1.5. Observe this simple snippet from the middle of my test:
i1 = 127; i2 = 127; i3 = 127;
i1 = 128; i2 = 128; i3 = 128;
Looks simple enough... set three integers to the same number, test if they are the same, and print true if they are equal... but here's the output:
Analysis: apparently 128 does not always equal 128... Whoops!
My gut feeling is that this should never be possible. It wasn't in Java 1.4, or any other language I know... Of course, I left out the most important part of my test code -- the declaration:
Now it should be clearer to the Java bunnies... The variable i1 is an integer primitive, whereas i2 and i3 are Integer objects. As we all know, the equals operator i2==i3 tests if two things are the exact same object in the computer's memory... whereas the equals method i2.equals(i3) tests if they have the same value. That's an important distinction for any object-oriented language.
So, what's the big deal? This was always a problem, right? You'd have the same issues in all versions of Java.
Yes, but that's not the point... In older versions of Java the code would have to be this:
i1 = 128;
i2 = new Integer(128);
i3 = new Integer(128);
Autoboxing is basically shorthand. It allows you to define and change the value of objects as if they were primitives. The first code snippet would never compile in Java 1.4, and nobody was confused about it. Now, I'm all for shorthand... but this is going to cause more problems than it solves.
If you just take the first code snippet, any reasonable person would balk if all tests didn't return true. If you were forced to set the new values as if they were objects, then any proficient Java hacker would know to use the equals method. But if you use this shorthand all over, you might forget if that variable is an object or a primitive.
Even if you do use the equals operator with numbers, you still have to be careful with types. There are four kinds of integer objects, Byte, Short, Integer, and Long. Count 'em, four! Naturally, if you want to compare numbers, you need to use the equals operator. However, you better make sure that the objects are the same type... otherwise zero will not equal zero:
Long l1 = 0L; // autoboxing shorthand
System.out.println(l1.equals(0L)); // true
System.out.println(l1.equals(0)); // false
The first test compares a Long with value zero to another Long with value zero... the second compares it with a Integer with value zero. Although they are both integers in the abstract sense, they are different types of objects, so the equals operator fails. Zero does not always equal zero.
I stand by my assertion that object-oriented zealots encourage people to abstract away the wrong information...
Note, this behavior makes total sense for almost all objects: if they are not the same type, how can the equals method possibly make any sense? But some argue, as I do, that primitives are already special cases, and should be treated as such... especially when you are talking about integers. Every hacker knows you shouldn't compare a zero integer to a zero floating-point number... but zero should equal zero for all integers, regardless of sub-type.
Sun should have tried harder to make sure things make the most sense to the most people... they shouldn't simply pander to those who drank the object-oriented kool-aid. Somebody from the C programming world would expect a compiler warning... people from the PHP/Python/Perl/Ruby camp would expect it to 'just work'. Even Java 1.4 folks would look at it sideways for a moment...
In either case, prevent the uninitiated from writing financial apps in Java!
This has been in development for around ten years, and has demonstrated an incredible ability to break down smog into more manageable compounds. By repainting (or repaving) 15% of urban surfaces, they suspect you could cut pollution in half.
Not only that, but it even acts as a preservative. By covering a concrete surface with it, you can significantly reduce the damage caused by acid rain.
And its also pretty darn cheap... it would only increase the cost of a small five-story building by about $100.
Imagine how much cleaner California would be if they paved their roads with this stuff. Or how much cleaner New York City would be if they used this in plaster or paint.
That has got to be the best invention from Italy since the pizza... or maybe the Ferrari.