I read a very good article on breaking the crossdomain wall for Ajax requests. It's presented here, as an entry on http://www.wait-till-i.com. In it, Chris Heilmann talks about using a Yahoo service and JSON-P requests with Ajax to load any site's contents. You should most certainly read his article - it's fantastic. I post here the most salient bit (for me) since it genuinely knocked my socks off. To re-use this in your own code, copy the parts I've highlighted in bold. You can use your own version of jQuery, naturally, as the most interesting aspect is the bits inside the ajax function (which itself is pretty trivial. I created the wrapper function so that the code could be stashed away and re-used more readily). I demonstrate its use in the script fragment below that, where I load the HTML for this very site.
ajax
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title> ZOMG! </title> <link rel="stylesheet" href="styles.css" type="text/css"> </head> <body> <script src="http://code.jquery.com/jquery-latest.pack.js"></script> <script language="javascript"> function ajax( url, cb){ var yqlUrl = "http://query.yahooapis.com/v1/public/yql?"+ "q=select%20*%20from%20html%20where%20url%3D%22"+ encodeURIComponent(url)+ "%22&format=xml'&callback=?" ; $.getJSON( yqlUrl, cb ); } </script> <script language="javascript"> $(document).ready(function(){ ajax( 'http://www.joshlong.com', function(data){ alert( data.results[0] +'' ) ; }); }); </script> </body> </html>
I can't tell you how powerful overcoming the leap-before-looking temptation is when building a system. Have an object model? Model it using UML or ERD. Have a workflow? Draw a workflow diagram (an activity diagram). Have a webflow? Draw a webflow diagram (looks like a state diagram, or in more sophisticated scenarios, like an activity diagram). Have a site map? Map the site using a site planning tool like Denim. All of these tools facilitate VISUAL feedback. They are cognitive, high level disciplines, and for good reason! Your mind interprets things visually differently than it does when coding from the left brain - it is able to "see" associations between related concepts when it's fed ideas through feedback that ends up in the right brain.
I've mentioned this before, I think, but check out Neal Ford's On the Lam From The Software Police for more.
Even if you don't check it out, invest in trying the modeling tools associated with the task you're attempting to solve. Even if you feel - after giving the technology a REALLY good-faith effort - that you've gained nothing, I'm willing to bet your product will still be more "consistent" than if you had developed it from scatch, unable to see the big picture.
How are you handling messaging in your thin client, thick client, fat client, RIA, or mobile client?
BlazeDS provides the ability to proxy messages from a JMS destination. Your AIR / Flex client can subscribe to it and provide a callback, very much like a Message Driven EJB or Spring's Message Driven POJOs.
Traditionally, reacting to an event on a bus in a client (which very well could exist outside the firewall) means polling some service or setting up a specialized proxy or perhaps having separate DMZ-safe JMS destination where you forward client-bound messages.
Suffice it to say, all of this is tedious and imposes an unecessary burden on the architecture and the developers. When it comes to messaging and remoting based services, there is definitely an extra burden on the developer of a RIA to secure or handle that requirement where this burden simply does not exist with traditional web applications. It is too frequently glossed over when architecting a system and then becomes a pain point.
There are some tools...
If you are using AJAX for your RIA, then you will have mastered tools like comet for push-based messaging. Even here, though, the burden of connecting and configuring comet is on you, the developer. For example, DWR - which is fantastic - doesn't have a way of proxying a JMS destination that I know of. It can be done, of course.
David Dossot showed me a very interersting, albeit specific, solution that solves the problem for Ajax using ActiveMQ's JavaScript client.
So, back to the question at hand - how are you solving the problem? Do you just avoid building systems that have the problem? You truly can't think of at least one or two or a millino problems that would be better served by messaging?
To me, the most complete solution appears to be Flex partnered with Spring and BlazeDS. If this post sounds like that of a gushing fan boy, you'll forgive me. It's true, unbounded enthusiasm. This technology is liberating, enabling! It reduces a real problem to a half hour of configuration - relegating the architectural burden back to the "gloss over" column, if you're using Flex. The Spring - BlazeDS integration is more than just a lot of "could"s. It provides out-of-the box support for connecting to JMS, and if you use the excellent Spring/BlazeDS solution, then you can do all of this with aplomb, and you can hook up any flex client to any channel on your Spring Integration bus with a minimum of fuss.
Naturally, all of that will all be covered in Spring Web Recipes, so stay tuned!
So: how are you talking to your messaging middleware? Remember - messaging is even MORE important in the wild Web 2.0 / cloud world than the client-server applications of yesteryear. Temporal decoupling brings scalability.
I use PostgreSQL 8.3 - highly recommended by the way - and I just updated an application to 8.4. The application is built principally using Spring, Hibernate, and JMS. Naturally, some level of cooperation among transactions is required, so I use an XA provider - Bitronix. Everything was working swimmingly with PostgreSQL 8.3, but the application buckled on startup with errors when I upgrade PostgreSQL to 8.4:
Dec 30, 2009 11:25:50 PM bitronix.tm.twopc.AbstractPhaseEngine logFailedResources SEVERE: resource xasql failed on a Bitronix XID [737072696E672D62746D2D- 73656E64657200000125E3A04B9900000038 : 737072696E672D62746D2D73656E6465720- 0000125E3A04BA40000003A] org.postgresql.xa.PGXAException: Error preparing transaction at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:254) at bitronix.tm.twopc.Preparer$PrepareJob.run(Preparer.java:134) at bitronix.tm.twopc.executor.SyncExecutor.submit(SyncExecutor.java:12) at bitronix.tm.twopc.AbstractPhaseEngine.runJobsForPosition(AbstractPhaseEngine.java:109) at bitronix.tm.twopc.AbstractPhaseEngine.executePhase(AbstractPhaseEngine.java:71) at bitronix.tm.twopc.Preparer.prepare(Preparer.java:68) at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:176) at bitronix.tm.BitronixTransactionManager.commit(BitronixTransactionManager.java:95) at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ... Caused by: org.postgresql.util.PSQLException: ERROR: prepared transactions are disabled at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451
If you're in my situation, the immediate cure is to uncomment and set the max_prepared_transactions attribute in data/postgresql.conf. A safe value seems to be 10, though your mileage may vary. There must be a reason they've disabled this in 8.4, so further investigation is required. In the meantime, though, everything seems performant and works as it did before.
max_prepared_transactions
data/postgresql.conf
Spring 3.0's out (you didn't get the memo?), and there's a lot of interesting stuff. This release has been long in coming due in no small part to the specifications it tracks and to the intense furvor and emphasis placed on quality assurance and testing. One target platform - JEE6 (and with it the final versions of JSR330) - also just recently went final, and you'll find support for these technologies, as well, where appropriate. Now that it's out, you can start certifying applications in production on it. I've found that - aside from dealing with the new Maven imports - the upgrade process has been flawless. I've taken complex applications and merely fixed the jars and they continue to work. You will find, however, that there are a lot of reasons to go through and start selectively enabling new features, and namespaces.
In our book Spring Enterprise Recipes, my co-author Gary Mak and I discuss a lot of the new, exciting Spring 3.0 features. Spring 3.0 debuts slightly more streamlined scheduling / TaskExecutor / thread pool support. The idea is that you can more readily model asynchronous, repeating (at a scheduled time, rate, or both), and concurrent programming problems using these facilities and - in some cases - do so while leveraging more advanced facilities underlying a given target platform, like the WorkerJ implementations, the Java5 task executors, and thread pools and more.
I won't go into much of that here as the book ablely covers most of it, but one thing I did want to cover (which we couldn't cover in time in the book as the feature was not ready as the book went to press) was the very elegant task namespace.
task
It should be noted that these features are not, exactly, novel. Spring has shipped with a Quartz scheduling framework integration for years. Among many other niceties included therein was (and still is, for what it's worth) a MethodInvokingJobDetailFactoryBean that allowed you to schedule future executions of a method on a Java bean using Quartz.
A few years later, EJB 3 debuted support for a limited form of scheduling using the Timer mechanism. One major limitation was the lack of support for CRON-like expressions and for asynchronous methods. Naturally, you could use JMS to acheive the same effect, in a way...
Timer
The JBoss gang debuted JBoss Seam support for scheduled and asynchronous method execution on a Seam component as well as a proprietary mechanism to do the same with EJB 3. In Seam, using these features was simply a matter of adding the appropriate configuration (as we do in Spring) to enable the executor (they have a few, including one based on the EJB3 Timer and one based Quartz.) The usage here is familiar to what has recently been debuted in Spring 3.0.
Clearly, the need for such features is common enough that they've both been fully incorporated into JEE6 and EJB3.1. There, you can specify CRON expressions as well as defer the invocation of a method using the @Asynchronous or @Schedule annotations. A simple example looks like:
@Asynchronous
@Schedule
package com.joshlong.ejb.timer ; import java.util.Date; import java.util.logging.Logger; import javax.annotation.Resource; import javax.ejb.Schedule; import javax.ejb.Asynchronous; import javax.ejb.Stateless; import javax.ejb.Timeout; import javax.ejb.Timer; import javax.ejb.TimerService; @Singleton public class PeriodicGreeter { // you could use this to schedule things manually @Resource TimerService timerService; // or use the annotations to do so automatically @Schedule(minute="*/3", hour="*") public void sayHelloPeriodically() { System.out.println( String.format( "Hello, world, at %s" , new Date()) ) ; } @Asynchronous public Future<String> sayHelloAsynchronously() { System.out.println( String.format( "Hello, world, at %s" , new Date()) ) ; // ... } }
The task namespace let's you declaratively configure a TaskScheduler and a TaskExecutor instance using XML. From here, you can configure beans that have scheduled, or asynchronous, executions using the XML or - my personal favorite if you can get access to the code - via Java annotations.
TaskScheduler
TaskExecutor
Here's an example Spring application context featuring this namespace and configuring a scheduler and executor with default-ish settings:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <context:annotation-config/> <context:component-scan annotation-config="true" base-package="com.yourbasepackage.scheduling" /> <task:scheduler id="scheduler" pool-size="10"/> <task:executor id="executor" pool-size="10"/> <task:annotation-driven scheduler="scheduler" executor = "executor" /> </beans>
What you do from here is up to you. You could simply start defining tasks inline with your XML. That approach certainly has its redeeming qualities, not the least of which is that your code is more readily "documented" and conceivably adjustable at runtime with some refresh trickery... sure.. you could.
<task:scheduled-tasks scheduler="myScheduler"> <task:scheduled ref="greeter" method="sayHello" fixed-delay="5000"/> <task:scheduled ref="greeter" method="sayHello" fixed-rate="5000"/> <task:scheduled ref="greeter" method="sayHello" cron="*/5 * * * * MON-FRI"/> <task:scheduled-tasks/>
...In practice, however, the annotation approach just FEELS soo much better! So, here is how you might write a scheduled or asynchronous bean in Spring.
package com.joshlong.spring.timer ; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.Date; @Component public class SpringPeriodicGreeter { // you can do everything you normally would using Spring, obviously @Autowired CustomerService customerService ; // this runs once every 5 minutes @Scheduled(fixedRate = 1000 * 60 * 5) public void sayHelloEveryFiveMinutes() { System.out.println( String.format( "Hello, world, at %s" , new Date()) ) ; } @Scheduled(cron="*/5 * * * * MON-FRI") public void sayHelloOnlyOneWeekdays() { System.out.println( String.format( "Hello, world, at %s" , new Date()) ) ; } @Async public void doSomething(String s) { // this will be executed asynchronously } @Async public Future<String> returnSomething(int i) { // this will be executed asynchronously, but you can get the // result by blocking on Future.get } }
Future.get
Thus, this is nothing too strange - very simialar in fact to what's in JEE6. Obviously, I've not mentioned every permutation of the features from the various technologies, but hopefully this gets you past the initial cognitive "hump" of adapting a new technology. It helps that - at least in the Spring case - it's dead simple to start using it if you're already using Spring. I wonder if there will be support for working with the JEE6 annotations that describe the same things? The major takeaways are that you can get this simply by updating your version of Spring, which should be painless if you're not tied to Java 1.4. You can get the JEE6 functionality by updating your version of the platform and server, if the platform/server are ready (Glassfish is!).
Now, as to where this stuff might be used, well, I can only think of a few thousand things...
@Async
Waiting for a long running process to finish up. Started screwing around on the internet and found a useful little application called TweetCloud. It generates a neat looking image-based cloud of your tweets. Here's my tweet cloud. I'm @starbuxman, if you're on that busy network and wanna chat.
If you've ever had to do batch processing, then you know how tedious it can be to write all the infrastructure code surrounding retries and error recovery and usefully handling long running processing and all the other tedium that surrounds a typical batch application. For these types of applications, I use Spring Batch, a batch processing framework from Dave Syer and the fine people at SpringSource.
The basic idea is that you setup jobs that have steps, that have tasklets. This the normal use case, but by no means the only one. You use jobs and steps to string together sequences of processing input and writing to output via a reader and a writer. Spring Batch has implementations for both reading and writing that will likely meet most of your needs: XML, files, streams, databases, etc. There's so much interesting stuff here, so of course I humbly recommend you take a crack at the documentation or read my book, Spring Enterprise Recipes.
job
step
tasklet
reader
writer
That said all said, there's no obvious way to read from an input source and then write to multiple files. The use case here, in my case, is Google's Sitemaps. These are XML files that describe the pages on your site. You list every URL possible. If you have more than 50,000 links, then you must create many files and list those files in a Sitemap index file. So, I wanted to read from a database and derive all the URLs possible for content, and then write those to sitemap XML files, where each sitemap could not exceed 50,000 entries. Spring Batch ships with an adapter writer that serves exactly this purpose. It's called org.springframework.batch.item.file.MultiResourceItemWriter. You define it just like you might any other writer, except that you wrap another writer with it.
org.springframework.batch.item.file.MultiResourceItemWriter
Here's the salient bits from my configuration. Most of this is boilerplate. I don't include the configuration of the Spring Batch environment, or the configuration of the reader, because those are pretty typical. Note that here we configure the writer for the job and in turn configure its delegate property, where we have the real writer implementation. In this case, there's no need to configure the delegate writer's resource property.
delegate
resource
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <beans:import resource="batch.xml"/> <job id="batchForCreatingSitemaps"> <step id="sitemap"> <tasklet> <chunk reader="reader" writer="writer" commit-interval="${job.commit.interval}"/> </tasklet> </step> </job> <beans:bean id="siteMapLineAggregator" class="com...sitemapscreator.SiteMapLineAggregator"> <beans:property name="domain" value="${sitemaps-domain}"/> </beans:bean> <beans:bean class="com...sitemapscreator2.ResourceSuffixCreator" id="resourceSuffixCreator"/> <beans:bean id="writer" scope="step" class="org.springframework.batch.item.file.MultiResourceItemWriter"> <beans:property name="resource" value="file:#{jobParameters[outputResourcePrefix]}"/> <beans:property name="resourceSuffixCreator" ref="resourceSuffixCreator"/> <beans:property name="saveState" value="true"/> <beans:property name="itemCountLimitPerResource" value="50000"/> <beans:property name="delegate"> <beans:bean class="org.springframework.batch.item.file.FlatFileItemWriter"> <beans:property name="encoding" value="UTF-8"/> <beans:property name="shouldDeleteIfExists" value="true"/> <beans:property name="lineAggregator" ref="siteMapLineAggregator"/> </beans:bean> </beans:property> </beans:bean> <beans:bean id="siteMapUrlRowMapper" class="com...sitemapscreator.SiteMapUrlRowMapper"/> ... </beans:beans>
I have a lot to be thankful for. This year saw my wife and I move to Los Angeles, where we've been well received in new jobs and by family. I've experienced success speaking at various conferences, and this year saw the publication of my first book, Apress' "Spring Enterprise Recipes." Recently, I was in a pretty bad accident (a big-rig rear-ended me) and I emerged alive. I have a wonderful wife who has always supported me, and I have made good friends. I am thankful for the readers of my blogs. I am thankful for my loving friends and family.
I hope you have a long list of things for which you're thankful, too. Happy Thanksgiving!
Warning: Shameless Plug I am pleased to announce that, after a long time and a lot of work, my first book Spring Enterprise Recipes (which I co-authored with the indefatigable, epic and extraordinary Mr. Gary Mak, author of - among many other things, Apress' Spring Recipes) has been released and is now purchasable. It should be hitting book stores soon, but in the meantime, you can buy the e-book at Apress.com, or you can pre-order it on Amazon.com.
The book discusses Spring 3, but also accounts for the many "modules" surrounding Spring with an eye towards building elegant, scalable systems with a minimum of fuss. Many of these modules have come from SpringSource, and some are independent third party projects that integrate well with Spring. Spring Enterprise Recipes introduces concepts like business process management (BPM), enterprise application integration (EAI), distributed computing and messaging and then grounds these introductions with real-world examples using Spring and lead open source frameworks.
This book discusses both the why and the how. It starts with a discussion of the usual suspects, exploring the quintessential tools in any developer's toolbox: RPC (RMI, Hessian, Burlap, Web Services, HTTP/Invoker, EJB 2 and 3, and more), messaging (via JMS), database access (JdbcTemplate, and a few of Spring's numerous supported ORM abstractions), transactions (e.g., various transaction abstractions supported by Spring), and numerous services like e-mail, JMX, worker pools, and scheduling infrastructure.
Then, we progress into more advanced solutions. This book includes the first-in-print or most updated coverage of a lot of technologies, including Spring Integration (a lightweight ESB-like integration framework for EAI), Spring and jBPM 4 for business process management, GridGain for grid computing, Terracotta for clustered state managment, Spring Batch for batch-processing solutions and OSGi to bring modularity to your application.
In the large, this book is a gentle, but comprehensive introduction to the best-of-breed solutions for tomorrow's architecture using Spring and other lightweight, powerful tools. Having said all that, I hope you'll consider it for your next purchase and that it helps you solve some interesting problems and build even more interesting solutions!
Go, a new language from Google, has created quite a stir. It has a great pedigree, owing to renowned experts like Rob Pike (a member of the Unix team, and a creator of the Plan 9 OS from Bell Labs.) The language is a procedural language (like C, or Python) which offers a strongly typed, but flexible type system (not centered around object-oriented facilities as we know them from languages like Java and Ruby). The syntax is a strange mix of C and Python. Honestly, it feels like C when you read it, but it writes more like Python - lots of features in the syntax that are designed to be consistent, predictable.
One blog entry prompted a very lively discussion of the language: it made the comparison that Go seemed awfully similar to Algol 68, a language 40 years past irrelevance. The blog entry said that while Algol 68 was a nice language, Go might be considered an efficient language. It claimed that efficient languages are the ones that - ultimately - propagate. Witness COBOL, C, C++, and Java, for example. Go, thus, may very well be a very efficient language, but it's not even close to a nice language. It's a lost opportunity.
Programming languages tend to come and go, but they all advance basing their innovation in some small part on their predecessors. Programming languages have to evolve slowly. Languages do not exist in a vacuum. They must respect the work that's preceded them, while innovating. They must strike a careful balance, never alienating the existing community, the legacy base, and always advancing the state of the art. Doing so incorrectly can be the biggest sin a language can make. Kowtowing to the legacy of C crippled the evolution of C++, leaving it a confusing mix of phantom requirements and artificial features. Conversely, Java achieved meteoric propagation because it looked and felt like C++ without many of the warts. This made the transition to Java easy. Compatibility is a double edged sword.
Most recent languages look and feel like C/C++. They've innovated ever so slightly, inducting into the syntax features formerly handled by libraries. Or, the language is flexible enough to support requirement-specific DSLs. You can see this with Scala and Groovy, Ruby and C#. They're all fairly familiar, but offer advantages in their grammar over their predecessors. C#, for example, introduced LINQ, while Scala surfaced its concurrency facilities as an Actors DSL. The idea of a language syntax as a differentiators is even more relevant of late. The .NET runtime popularized the idea of a multi-language run time. It meant that choosing a language did not mean forsaking libraries. The JVM has matured, and there are many languages implemented atop it, as well. Other infrastructure VM projects have emerged, like the LLVM.
So, I don't blame Go for looking so much like its predecessors. That's the cost of doing business. It's intended to be a general purpose language, after all. It does have a few unique features surfaced as language constructs, like intrinsic concurrency facilities, which it calls gorountines.
I don't understand why they have built another virtual machine. If Go is going to innovate, it will be in its Virtual Machine. Why not the CLI, JVM, or LLVM? The language has strong support for interop - easily wrapping native code much like you might using C++. The .NET CLI supports this sort of thing, though. I understand the language needed to run on Unix (at the moment, you can't run it on Windows!), and perhaps Mono wasn't sufficiently advanced. Why not the JVM? Would building that kind of infrastructure be that hard? What about the LLVM? It seems well suited to working on Unix and to handling interop. Perhaps interop is not the only concern. The implementation of the goroutines seems to have been a priority. The language does not yet have assertions or exceptions specifically because doing so would be awkward with goroutines. This language, as Mr. Pike explained it, was created for Google to build servers. Cheap, and efficient threading was priority #1. This piques my curiosity. Why could the JVM - which hosts Scala and Clojure - not be used to build goroutines. Is there some fundamental flaw that makes concurrency on the JVM a non starter? I don't understand.
I would agree that the language is not particularly novel. What I don't understand is why the VM is novel. Clearly there are requirements I don't understand, and this is why I think Go will be worth paying attention to, in much the same way Erlang is.
There is also something refreshing about a genuinely new language. New platform, new libraries, new syntax. Programs written in a language like that represent advances. Shortly after the debut of the language, a command line Twitter client emerged. The example is promising - by definition the implementation was from-scratch. It was quick, and the result is imminently readable.
Perhaps I'm over thinking this. Perhaps the language will be successful because it's simple, and efficient. Perhaps the VM is some how unique and better served by a custom implementation. Only time will tell.