Friday, December 21, 2007

Dear Santa, Here's My List

Dear Santa,

I have been good this year. I have written intelligent unit-tests with plenty of code coverage. No empty catch blocks and tried to stay aware of threading issues.

Here is my list for this year. Please see attached.

thank you,
Michael Easter

10. "Oh Crap" Customizations

I want to configure software so that it ignores my "Oh Crap" moves. e.g. If I click on the A: drive, I want Windows Explorer to ignore me. If I type "google.cmo" into Firefox, I want it to no-op.

9. Snopes Plugins

I want a plugin for Firefox and Outlook that will confirm links and text against Snopes and alert the user that the given email is a hoax.

8. JSnopes

I want a website that lists "urban myths of Java" and sets developers straight on the current best practices. e.g. advice like "use StringBuffers everywhere" from 2001. Still accurate, or myth?

7. A Cap on DZone Down Votes

I want users on DZone (with which I have no affiliation) to have a limit of 10 down votes per week. That way, poseur naysayers can't blithely vote down everything they see. If a person runs out of down votes, they can express themselves with a comment on the site or, better yet, their own blog.

6. Please let "spaces in filenames" be just a bad dream, from which we will awake

5. Fitness as Games

I want treadmills, rowing machines, and other fitness equipment to be networked via games so that my gym becomes as fun and popular as an arcade.

Given the age/weight of Person A and Person B, weight the difficulty so that it's a fair battle. e.g. Can my heart-rate stay lower at 7.5 mph than yours at 5 mph? Then use this data to drive truly creative 3D games.

4. Python

I want to give Python at least half the coverage that Ruby gets. It deserves it. e.g. Why is it one of the very few approved languages at Google? Discuss.

3. Microsoft DeveLista

I want a version of the Microsoft OS that is geared toward developers:

  • No applications or bloatware.
  • Just give me the file system, drivers, registry etc, and the ability to add programs.
  • I might even pay the same amount IF you give me a modern way to edit environment variables!
2. Closures

I want the closures debate to be: rational, civil, and at times light-hearted. So far, so good, but I'm worried that things are going to get hot.

Jokes/spoofs are fine by me. The ideas put forth by the Big Players have been well-thought out, and even the regular joes are making sense. I just hope it stays that way.

1. Taser Task

I want an Ant Taser task that will send a signal to a USB taser and zap anyone who breaks the build. This includes me. I think it will make the workplace more fun.

Bonus points if the task can play a sound file of "Don't Tase Me, Bro" just before delivering the juice.

Thursday, December 13, 2007

Scala at St Louis JUG

Looking for something to do on a Thursday night, for a ray of sunshine in an otherwise bleak and desolate week?

Need a break from the hustle and bustle of holiday shopping?

Want some new icebreakers for a holiday party, so you can impress that person from Marketing?

Well, then come on out to the St Louis Java Users Group. Tonight, Tim Dalton will be presenting on Scala. I'm looking forward to it: a shiny new language!

If you can't make it, or aren't in the area, check out Tim's article over on the OCI Java News Brief.

Wednesday, December 12, 2007

Zero to RMI with Groovy and Spring

In a recent post, I leveraged Spring to write a simple client-server app using 50 lines of Java.

I've moved it to Groovy. I've included the code below, but here are some fast facts:

  • I used groovyc to compile the Groovy to class files, then used the java command.
  • I could only reduce the code by an import or two. However, I did save 220+ characters (notice how clean the Groovy is). Groovy gurus might be able to improve on this.
  • Note that the Spring config files have more namespaces for Groovy support. Discovering this was the hardest part of the exercise.

Here is the contract between the client and server. This would be in a common package:


interface EasyServer {
Message exchangeMessage(String user)
}

Here is a simple Message class. Of course, for RMI, being Serializable is vital:

import java.io.Serializable

class Message implements Serializable {
private final String message

Message(String message) { this.message = message }

String getMessage() { return message }
}

So far, so good. Now the server implementation:

import org.springframework.context.support.ClassPathXmlApplicationContext

class EasyServerImpl implements EasyServer {

Message exchangeMessage(String user) {
return new Message(user + ", Spring with Groovy rocks!")
}

static void main(String[] args) {
def context =
new ClassPathXmlApplicationContext("server_config.xml")
context.getBean("easyServer")
println("server ready")
}
}

It defines an easy exchangeMessage method and a starting main method. Spring takes care of the rest, as shown in the server_config.xml file:

<?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:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-2.0.xsd">

<lang:groovy id="easyServer" script-source="classpath:EasyServerImpl.groovy"/>

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- does not necessarily have to be the same name as the bean to be exported -->
<property name="serviceName" value="easyServerService"/>
<property name="service" ref="easyServer"/>
<property name="serviceInterface" value="EasyServer"/>
<!-- defaults to 1099 -->
<property name="registryPort" value="1199"/>
</bean>

</beans>

For running and compiling the server, simply ensure that these are in the CLASSPATH:
  • SPRING_HOME/dist/spring.jar
  • SPRING_HOME/lib/jakarta-commons/commons-logging.jar

Then it is up and away:

$ java EasyServerImpl

[ Spring magic dust snipped ]

server ready

The client is even simpler:

import org.springframework.context.support.ClassPathXmlApplicationContext

class EasyClient {
private EasyServer easyServer

void setEasyServer(EasyServer easyServer) { this.easyServer = easyServer }

Message exchangeMessage(String user) {
return easyServer.exchangeMessage(user)
}

static void main(String[] args) {
def context =
new ClassPathXmlApplicationContext("client_config.xml")

def easyClient = context.getBean("easyClient")

String output =
easyClient.exchangeMessage("CtJ Reader").getMessage()
println( output )
}
}

The client-side configuration XML:

<?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:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-2.0.xsd">

<lang:groovy id="easyClient" script-source="classpath:EasyClient.groovy">
<lang:property name="easyServer" ref="easyServer"/>
</lang:groovy>

<bean id="easyServer" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:1199/easyServerService"/>
<property name="serviceInterface" value="EasyServer"/>
</bean>

</beans>

Using the same CLASSPATH, but with a separate window, we establish contact like so:

$ java EasyClient

[ Spring noise snipped ]

CtJ Reader, Spring with Groovy rocks!


Cool stuff...

Tuesday, December 11, 2007

JetBrains Gets It

There was a tidbit couched in the recent announcement about Groovy 1.5: there is a joint compiler that eases the compilation of projects that use both Groovy and Java.

I want to highlight that JetBrains contributed it.

I have no affiliation with the company. I simply think that is very cool and a savvy business move with respect to goodwill.

From the Open Musings Department:

As I write this, I was about to joke that the joint compiler code might have an advertisement in the comments:


///////////////////////////////////////////
// "Brought to you by JetBrains, makers of Idea"

Maybe that's an idea? Hockey rinks, race cars, and baseball parks are plastered with ads: what if open-source projects allowed (regulated) ads in (a) the comments or (b) the startup console. Would that encourage contributions? Would it cause political issues? Hmmm.....

Monday, December 10, 2007

Zero to RMI in Minutes (or I *heart* Spring)

Recently, I paired with a colleague and sought to experiment with detached objects in Hibernate across a remote connection. Armed with some POJOs and Hibernate files from a project source tree, we decided to write a toy client and server from scratch.

(Admittedly, we had experience with Spring IOC: this is not a tutorial.)

We were fully experimenting with the sandbox in 75 minutes. This may not seem fast but it was astonishing: some days, it seems I can't empty my Recycle Bin in 75 minutes.

Partly for my own reference, but also for CtJ readers, here is a recap of the RMI portion. No Hibernate here. And an extremely "toy" project structure (e.g. no Ant, no packages). But the key idea is there, and it will showcase the power of Spring.

We used Spring 2.5. To be honest, I don't know if this is in Version 1.x. It may well be.

Here is the contract between the client and server. This would be in a common package:


interface EasyServer {
Message exchangeMessage(String user);
}

Here is a simple Message class. Of course, for RMI, being Serializable is vital:


import java.io.Serializable;

public class Message implements Serializable {
private final String message;

public Message(String message) { this.message = message; }

public String getMessage() { return message; }
}

So far, so good. Now the server implementation:


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EasyServerImpl implements EasyServer {

public Message exchangeMessage(String user) {
return new Message(user + ", Spring rocks!");
}

public static void main(String[] args) {

ApplicationContext context = new
ClassPathXmlApplicationContext("server_config.xml");

context.getBean("easyServer");
System.out.println("server ready");
}
}

It defines an easy exchangeMessage method and a starting main method. Spring takes care of the rest, as shown in the server_config.xml file:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.5.xsd">

<!-- EasyServerImpl is the implementation -->

<bean id="easyServer" class="EasyServerImpl">
</bean>

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- register the impl as the 'easyServerService' -->
<property name="serviceName" value="easyServerService"/>
<property name="service" ref="easyServer"/>
<property name="serviceInterface" value="EasyServer"/>
<!-- defaults to 1099 -->
<property name="registryPort" value="1199"/>
</bean>

</beans>

For running and compiling the server, simply ensure that these are in the CLASSPATH:
  • SPRING_HOME/dist/spring.jar
  • SPRING_HOME/lib/jakarta-commons/commons-logging.jar

Then it is up and away:


$ java EasyServerImpl

[ Spring magic dust snipped ]

server ready

The client is even simpler:


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EasyClient {
private EasyServer easyServer;

public void setEasyServer(EasyServer easyServer) {
this.easyServer = easyServer;
}

public Message exchangeMessage(String user) {
return easyServer.exchangeMessage(user);
}

public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("client_config.xml");

EasyClient easyClient =
(EasyClient) context.getBean("easyClient");

String output =
easyClient.exchangeMessage("CtJ Reader").getMessage();

System.out.println( output );
}
}

The client-side configuration XML:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.5.xsd">

<bean id="easyClient" class="EasyClient">
<property name="easyServer" ref="easyServer"/>
</bean>

<bean id="easyServer"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl"
value="rmi://localhost:1199/easyServerService"/>
<property name="serviceInterface" value="EasyServer"/>
</bean>

</beans>

Using the same CLASSPATH, but with a separate window, we establish contact like so:


$ java EasyClient

[ Spring noise snipped ]

CtJ Reader, Spring rocks!

This trivial example uses approximately 50 lines of Java, with no knowledge of RMI. Amazing. It an easy exercise for the reader to package it up into a more formal project, using Ant etc. It is more challenging to add Hibernate, but still tractable: the basic wiring for a client-server playground is right here.

I'm curious as to how many lines of code this would take in Groovy. I think 40 would be easy to attain.

That's cool. I *heart* Spring!

ps. I lifted "*heart*" from Eric.

Tuesday, December 4, 2007

Zen and Groovy's Expando

In the past, I had trouble remembering the concept behind Groovy's Expando class. I knew it wasn't difficult but it was elusive. Perhaps I was distracted by the groovy-ness of the name.

In a recent training class with Jeff Brown, I was struck by a metaphor.

Readers of CtJ know the old refrain of dynamic-typing:

If it walks like a duck and quacks like a duck, I would call it a duck.

In other words, if "it" can provide the desired behaviour (e.g. quacking), then it can pass for a duck, in so far as a dynamic language cares. Cool beans.

Well, in Groovy, the Expando class is an empty "it"! It is a container for various behaviours, to which we can add stuff. Check out this code sample:


// tests the incoming, purported "duck" to see
// if "it" really quacks
def duckTester = { duck ->
duck.quack()
}

////////////////////////// Main

// create "it"... it cannot quack -- yet
def it = new Expando()

// add quacking
it.quack = { println "quack!" }

// call test: "if it quacks like a duck"
duckTester.call(it)
See? We create "it", then add quacking behaviour, and then test it. Easy. This prints
quack!
to the console.

Question: does anyone know the origin of the Expando name?

I've searched but not found it.

ps. A less glamorous way of thinking about it is that Expando is a map of methods and attributes. I'm sticking with ducks and it.

pps. Expando's are especially useful for mocking objects in unit-tests.

Monday, November 26, 2007

My New Favourite Analogy: Design Like Water


I am a big fan of analogies and metaphors. When I think of a good (or funny) one, it is often the very definition of a good day.

Well, I discovered a doozie. Influenced by positive reviews from several corners, I have been reading a bit of the book Getting Things Done. Though only mentioned in passing at the beginning, GTD mentions a beautiful idea.


Mind Like Water

The book describes an image from Karate: Mind Like Water. The idea is that, in Karate, a state of perfect readiness is having a "mind like water". Water (e.g. a lake) responds perfectly to a disruption; that is:

Water reacts appropriately and then returns to a calm state.

If one throws a pebble into a pond, there's a ripple, then calm. If one lobs a boulder, then there's a huge splash, then calm. The reaction fits perfectly, and the disruption is dismissed.

Design Like Water

For me, that is a beautiful analogy for all kinds of things in computer science. This is all very subjective, and hard to quantify, but consider this:

Shouldn't a software system (e.g. web application) be designed like water? i.e. A small number of requests should be a pebble; perhaps a Superbowl TV ad spawns a massive boulder. But in all cases, it should react appropriately and then return to a calm state.

Some real world examples include the Big Databases and the massive e-commerce sites. One doesn't hear of eBay or Amazon "being rebooted". They're designed like water.

What about computer languages? Though hopelessly whimsical, it strikes me as beautiful: a language should barely react to small things. It is allowed to require a big splash for big things, but ultimately it should shrug off the disturbance and provide calmness.

Specifying examples for languages is much more difficult, because the idea is so abstract. Long time readers will predict, correctly, that I'll offer Python as an example. It's a big pond of OO, functional capability, and brevity that seems to react appropriately to both pebbles and boulders.

What do you think? Do you buy the metaphor? If so, which languages resonate for you in this philosophy? Does Java or C# ?

Wednesday, November 21, 2007

Ctrl-Space Invaders

Ctrl-Space Invaders: The scenario where a user of Idea will use Ctrl-Space to view a list of available methods on an object, and search by pressing keys for the first letter of the method, with a fervor that is reminiscent of an early 1980s arcade game. Coined by a teammate.

Hey, can you tell me how to send a holiday greeting with a List? I've been playing Ctrl-Space Invaders for 10 minutes and don't see it.


Tuesday, November 20, 2007

Ambient Info: Hear Your Build

In a previous post, someone commented that wacky comments brighten one's day.

True that. So, too, does Ant's sound task. On past projects, we used it to denote a failed or successful build. We used:

Not only was it fun (as James Brown sang throughout various cubes) but it was a great way to subconsciously know the state of the build. This is a small example of ambient information. (For a far cooler example, check out this device built by Kohsuke Kawaguchi).

Does your project use the Ant sound task? What sounds does your team use?

Here are some ideas.....

For Success
More fun (or painful) are ideas for Failure:
Add your own ideas in the comments!

Thursday, November 15, 2007

My Grails Aha Moment

Recently, I attended a training class led by Gruru Jeff Brown. (A Gruru is a Guru in Groovy & Grails, esp. if one is a committer)

I have some experience with Groovy and plenty experience with webapps, but none with Grails, nor with Ruby on Rails.

Here's a few neat tidbits that I discovered:

  • In terms of configuration, Grails has no XML and the only properties files are i18n messages. Almost everything else is Groovy. I am familiar with 'convention over configuration', but I didn't know the configuration was so fluid and dynamic.
  • Many of the language features of Groovy become perfectly obvious in the context of Grails. The big one, for me, was named parameters. As a Groovy language feature, I was neutral on it; in the DSL setting of a web application, the feature is vital. Similarly for closures and other constructions.
  • Also, the MOP (Meta-Object Protocol) becomes extremely important. However, it is so sublime that it is hard to "see". That is, the Groovy code looks so lucid that it is easy to gloss over the machinations behind the scenes.
The Moment

In Grails, we created a test application, and created a domain class.

Subsequently, we created an MVC controller for our app. At this point, we had a barebones app that could be launched and viewed.

Cool beans. However, the turning point for me was that Jeff said we could generate a controller: that is, Grails would generate the full code and then we could tweak it. Without a hint of irony or coyness, he warned us that it would generate a lot of source-code.

Being from the Java world, I braced myself for the output. Surely it would be verbose, impenetrable, and a rats nest in terms of formatting.

Surprise: the generated Groovy was gorgeous. Due to the brevity and style of the language, the generated code was 2 screens long -- without doc. And I was able to grok it and start tweaking it immediately.

At first, I just started changing some code. But then I realized that I was working with generated code. That was the profound moment. I understood.

Below, I've provided the generated code for a Gambler controller (think of a casino app) on my local machine. Give it a glance.... As a hint, the controller contains several methods which are actions (in MVC parlance) on either a target Gambler object or a list of Gambler objects.

Note that I'm not asking if you can understand it cold. I'm asking "do you think you could understand it, if warm?". Remember... this is generated.

Personally, I think it is stunning.

Final Score: Grails 1 My Old Biases 0. Check out Grails here.

class GamblerController {

def index = { redirect(action:list,params:params) }

// the delete, save and update actions only accept POST requests
def allowedMethods = [delete:'POST', save:'POST', update:'POST']

def list = {
if(!params.max) params.max = 10
[ gamblerList: Gambler.list( params ) ]
}

def show = {
[ gambler : Gambler.get( params.id ) ]
}

def delete = {
def gambler = Gambler.get( params.id )
if(gambler) {
gambler.delete()
flash.message = "Gambler ${params.id} deleted"
redirect(action:list)
}
else {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:list)
}
}

def edit = {
def gambler = Gambler.get( params.id )

if(!gambler) {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:list)
}
else {
return [ gambler : gambler ]
}
}

def update = {
def gambler = Gambler.get( params.id )
if(gambler) {
gambler.properties = params
if(!gambler.hasErrors() && gambler.save()) {
flash.message = "Gambler ${params.id} updated"
redirect(action:show,id:gambler.id)
}
else {
render(view:'edit',model:[gambler:gambler])
}
}
else {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}

def create = {
def gambler = new Gambler()
gambler.properties = params
return ['gambler':gambler]
}

def save = {
def gambler = new Gambler(params)
if(!gambler.hasErrors() && gambler.save()) {
flash.message = "Gambler ${gambler.id} created"
redirect(action:show,id:gambler.id)
}
else {
render(view:'create',model:[gambler:gambler])
}
}
}

Android, GWT, and Lingua Java

One can almost feel the Blogtomonous Collective try and wrap their minds around the Android SDK. Between the Mensa puzzle of the legal-speak and creative lure of the prize money, there is a lot to contemplate.

Looking back a week or so, there are some weird psychic fingerprints that led up to the announcement.

  • At the St Louis JUG, Andrew Prunicki presented a cool talk on the Javelin Stamp. This is a microcontroller that uses a Java-like syntax which compiles onto a JVM (of sorts). The VM doesn't have garbage collection. My theory is that it can't be licensed as true Java and so that the company chose the wonderfully clever name Javelin.
  • Eric "Photoshop till You Drop" Burke posted satire: Android shuns Java. The joke being, of course, that there is no way Android could shun Java: such a prediction would be as ill-fated as "Dewey defeats Truman". But Android does shun the JVM!
I think we are seeing an interesting dichotomy:
  • On one hand, JVM Tunneling implies that the JVM is The Thing. Scala, JRuby, Groovy, and others all run on the JVM. Java is being marginalized as merely one syntactic "view" of the virtual machine. It's not even the coolest view going these days.
  • On the other hand, Javelin Stamp, Android and the Google Web Toolkit make the case that the Java syntax is The Thing. It certainly looks like Google believes it is the Lingua franca of our time. Who cares what transformations take place, as long as we have the apple pie of "public class MyClass {}" !
Call it Lingua Java.

This just in: we are in interesting times.

Tuesday, November 13, 2007

Trivial Pursuit: Unit-Testing Getters and Setters

While I was in Vegas, Eric, Alex, and Brian posted some ideas on unit testing trivial code.

The question: should we unit-test everything? The hive-mind currently says: yes.

E.g. Relevance recently posted a job offer that mentions 100% code coverage. At a recent NFJS, Stuart Halloway made the point that code coverage is one of the few things where one has to be extreme: 80% doesn't work; it has to be 100%. (Relevance is adamant on this point.)

Fine, so the answer is yes. But how do we remove the tedium of writing that testing code?

  • Modern IDEs generate code for getters/setters. They should do the same thing for generating unit-tests for this code. I haven't seen this: perhaps they already do? I've looked in Idea 6 and didn't see anything obvious.
  • It seems possible to write an abstract base class for unit-tests that uses reflection to auto-test common getters/setters. Is there such a tool out there?
  • Interestingly, we are seeing the impact of this issue in language development. Groovy will auto-generate getters and setters for a class member if they aren't provided. Not only is there less code to read, but also there is less code to test.
Post a comment if you know of a neat method to facilitate this testing...

ps. Here is a post from last winter on my experiences with unit-testing: in particular, TDD. It was a true growth experience for me.

pps. Here is the obligatory acknowledgement that getters/setters should not be automatically provided without just cause!

Thursday, November 8, 2007

The Name Game: Improve on Map for Java 7

What's in a name? that which we call a map
By any other name would associate as sweet;
-- with apologies to The Bard

Kevin Bourrillion has posted a joint proposal for minor additions to some core APIs in Java 7.

This is pretty cool stuff:
  • The proposal itself smacks of being agile: it's small in length and in scope.
  • The changes address some corner cases in the vein of Java Puzzlers, and fill some inconsistencies in various APIs.
The most interesting proposal, IMHO, is #7. The idea is to have a new Map interface that is fleshed out with new methods (those from ConcurrentMap) and have all Map implementations use that new interface.

Of course, we need a name for this new interface. The doc has this line:

not likely to happen, due mostly to lack of tolerable name

Like many thoughtful developers, my reaction is:

  • No doubt, names are important, and vitally so for a core API.
  • Can I come up with a better name?
  • Can I come up with an absurd name? (Delightfully, they offer MapDaddy)
  • Why can't I stop thinking about this?
I could write an entire post about the importance of names and how much fun/challenging it can be to find just the right name.

What would you name a new Map interface? Here are some of mine
  • Dictionary. Has a classic appeal to it, but is already used (and deprecated) in the JDK.
  • Lookup. Another classic but somehow it doesn't seem strong enough. It seems like we should have a derivative of 'Map'.
  • Map7. The doc cites this as a bad name but it makes my shortlist, for some reason.
  • ReplaceMap. Probably too cute, the idea here is (a) the new methods involve replacement and (b) we are replacing the Map interface. At this point, one starts to realize how hard this task is. I can understand the reluctance expressed in the doc.
and some more yet:
  • iMap. That will get Apple's attention.
  • NüMap. Java has great support for Unicode, so let's go Euro. Plus we could sell lots of Java 7 schwag to heavy metal fans and feed the proceeds back into the Open JDK.
  • Map#. We need to grab mindshare from from the .NET crowd before F# takes off.
  • MapQuest or GoogleMap. Now, we're on to something: Java could be the first language to embrace corporate sponsorship in its core libraries. Call Nike and CocaCola immediately! (though they will probably want to brand the String class)
Your turn. What do you think?

Tuesday, November 6, 2007

Las Vegas Lobbies for Java 6 on Leopard

CtJ Newswire
Las Vegas, Nevada

13949712720901ForOSX

With the recent news that Java 6 is absent from the Leopard edition of Mac OS X, CodeToJoy reporters went on location to Las Vegas. In the world-famous district known as The Strip, people protested in the streets, appealing directly to Apple CEO Steve Jobs.




Carrying signs that read "Java 6 for Leopard / Steve, hear our cry", the protesters staged a rally that spilled throughout The Strip and went on late into the night. Many people had traveled far and wide for the event, including such remote locales as Australia and Wyoming.




In the midst of the turmoil, Apple maintained its policy of secrecy. There were no reps at the protest, and text messages, intended for Steve Jobs, went unanswered, though possibly because his contact info was not at hand.



Organizers of the protest felt that the outing was ultimately a success. Only time will tell if Apple will respond to the lobby.



Friday, November 2, 2007

Searching Jars Redux

A previous post translated a Groovy file into Java using the closure proposal. The main goal was to see how the new Function Type fit into the Java syntax.

Unfortunately, as Neal pointed out, the resulting Java file wasn't very closure-esque. Here is the same idea, cleaned up.

The new file does this:

  • Accepts a search directory and a target string
  • Recursively traverses the search directory and, for each file found, applies a concept
  • The concept is, in essence, a closure. In this case, the concept is to (a) check to see if the file is a jar and, if so, (b) check the entry list of the jar for a target string
  • The key is that we now have an algorithm that calls a block of code. The block of code is bundled with any local state that it needs to process the input parameters.
Here is the code listing. It is very instructive to contrast (1) the original Groovy file (2) the first attempt at Java and (3) this program. Note that #2 in this list does something slightly different (i.e. it counts occurences, and does not traverse recursively).


import java.io.*;
import java.util.jar.*;
import java.util.Enumeration;
import java.util.*;

class FileExtension {
private String dirStr = null;

public FileExtension(String dirStr) {
this.dirStr = dirStr;
}

// @param block a closure
// @throws IOException (because the closure declares it)
// This method will recursively traverse a directory
// structure and call block for every file found.

public void eachFileRecurse(
{ File => void throws IOException } block
) throws IOException {
File file = new File(dirStr);

for( File thisFile : file.listFiles() ) {
if( thisFile.isFile() ) {
// file
block.invoke( thisFile );
} else {
// dir
FileExtension subFileExtension =
new FileExtension( thisFile.toString() );
subFileExtension.eachFileRecurse( block );
}
}
}
}

public class JarSearcher2 {
static final private String JAR = ".jar";
static private String target;

// closure block
// Iterates through a directory tree and applies the
// closure to each file
// @param file an input file
// @free JAR used as an extension
// @free a target string in a jar's list of entries
// @throws IOException

static private { File => void throws IOException } myClosure =
{ File file =>
String fileName = file.getName();

if( fileName.contains(JAR) ) {

JarFile jarFile = new JarFile(file);

// old-style Enumeration
// don't blame me or closures!
for( Enumeration e = jarFile.entries() ;
e.hasMoreElements() ; ) {
JarEntry entry = (JarEntry) e.nextElement();

if( entry.getName().contains(target) ) {
System.out.println("found " + target
+ " in: " + file.toString() );
}
}
}
};

// iterates through a directory tree and applies the
// closure to each file
// @param args[]
// @throws IOException
public static void main(String[] args) throws IOException {
String searchDirStr = args[0];
target = args[1];

(new FileExtension(searchDirStr)).eachFileRecurse( myClosure );
}
}

Thursday, November 1, 2007

Closure Puzzlers: Greetings


If you have read my previous post on the basics of the Java closures proposal, then you might enjoy the puzzler below. A double-reference to Neal Gafter: it uses his recent prototype and is in the vein of Java Puzzlers.

This is not designed to be an elegant example: I was experimenting with closure literals, function types, and free lexical bindings. 'Tis a simple introduction... A greeting, if you will.

What is the output from the following program?


public class Greetings {
static private Object freeVar = null;

static public void main(String[] args) {
{ String => String } greetings = null;

// @param greeting
// @free freeVar
// @returns a simple message String
greetings = { String greeting =>
greeting + ", I am " + freeVar };

freeVar = "a free variable!";
System.out.println( greetings.invoke("Hello") );

freeVar = new StringBuffer("a new ").append("value");
System.out.println( greetings.invoke("Bonjour") );

freeVar = greetings;
System.out.println( greetings.invoke("Hola") );

freeVar = { String self => self }.invoke("my self");
System.out.println( greetings.invoke("Shalom") );

freeVar = { => freeVar + " too" }.invoke();
System.out.println( greetings.invoke("Namaste") );
}
}


Don't cheat but here is the output. If you understand this output, then you understand the content of the original post.


$ newJava.bat Greetings

Hello, I am a free variable!
Bonjour, I am a new value
Hola, I am Greetings$1@10385c1
Shalom, I am my self
Namaste, I am my self too

I won't explain everything but here is a brief annotation:
  • The local variable, greetings, is declared with its function type, and initialized to null. This is a separate line in order to emphasize that it is a local variable with a new, strange type.
  • We assign a closure literal to greetings. Note that it uses a 'free lexical binding' called freeVar. One issue with the current prototype is that it does not yet bind local variables (hence the static member field).
  • We alter freeVar in various ways and let greetings construct a message based on its toString() method.
  • Note that the last greeting uses a truly literal closure that is invoked in situ.
Fun! If you liked this one, stay tuned for more.

Wednesday, October 31, 2007

Searching Jars with Java Closures

(Ed's note: see this post for a better example of closures. This one is intended for direct contrast with a Groovy script: the resulting Java is awkward.)

The last post has a "Hello World", of sorts, for Neal Gafter's closure proposal.

In it, I mentioned that I have converted a Groovy jar searcher into pure Java, using Neal Gafter's prototype.

Here is the code. It is probably best to understand the previous post before looking into this. I may also be instructive to understand the Groovy code first.

The code is documented but here is a view from space:

  • The program takes a directory and a target string as arguments. It searches all jars in the directory for the target string, and reports the number of matches found.
  • A use-case is that you are looking for MyMissingClass in a bunch of jar files.
  • The program uses 2 closures as private members to the class.
  • One closure is myEntryChecker, which accepts a JarEntry and uses the target variable as a 'free lexical binding'. It returns a boolean if the name of the JarEntry contains the target string.
  • The other closure is myFileChecker, which accepts a File and uses the above closure as a 'free lexical binding'. Note that this one declares an IOException.
  • Note that there is a cool proposal for loop abstractions that is not yet implemented. This will make run() much more elegant. In fact, the invocation of closures seems to be a major motivation for the proposal.
(Btw, if you find the example less-than-elegant, blame me, not closures. The intent is not to introduce closures, per se, but instead to illustrate the new Java syntax by leveraging a simple-yet-useful program implemented in Groovy.)


import java.io.*;
import java.util.jar.*;
import java.util.Enumeration;

public class JarSearcher {

private String target;
private String fileName;

// This closure checks a JarEntry's name for a target string
// @param jarEntry
// @return boolean true if found
// @free target the string we're looking for
// ('free' is my way of denoting a free variable)

private { JarEntry => boolean } myEntryChecker = {
JarEntry jarEntry =>
// expression! no return statement or semi-colon
// Thanks to Christian Ullenboom for the simpler version
jarEntry.getName().contains(target)
};

// This closure iterates over the entries in a jar file and
// checks each one for a target string (via another closure)
// @param file
// @return int # of occurences
// @throws IOException
// @free myEntryChecker
// ('free' is my way of denoting a free variable)

private { File => int throws IOException } myFileChecker = {
File file =>
int count = 0;

fileName = file.getName();

if( fileName.indexOf(".jar") != -1 ) {

JarFile jarFile = new JarFile(file);

// old-style Enumeration
// don't blame me or closures!
for( Enumeration e = jarFile.entries() ;
e.hasMoreElements() ; ) {
JarEntry entry = (JarEntry) e.nextElement();
if( myEntryChecker.invoke(entry) ) {
count++;
}
}
}

// expression! no return statement
count
};

// This method lists the files in a directory and
// uses a closure to check each file for a target
// string (if it is a jar file)
// @param args[]
// @throws IOException (because the closure declares it)

public void run(String[] args) throws IOException {
String searchDirStr = args[0];
target = args[1];

File searchDir = new File(searchDirStr);

// NOTE: Neal has a proposal that would make this
// iteration much easier
for(File file : searchDir.listFiles() ) {
int count = myFileChecker.invoke(file);

if( count != 0 ) {
System.out.println(
"found " + count + " match(es) in " + fileName );
}
}
}

public static void main(String[] args) {
try {
JarSearcher jarSearcher = new JarSearcher();
jarSearcher.run(args);
} catch(Exception ex) {
// TODO
}
}
}

Tuesday, October 30, 2007

Java Closures: A Quick Look


Neal Gafter is back! And he has brought treats for Halloween by way of a prototype on the closure proposal.

Essentially, it's a binary version of a modified JDK 6, released under the Java Research License. If Java is our home, Neal is building a whole new section, with a deck and swimming pool.

As a first exercise, I have converted my modest Groovy jar searcher into pure closure-Java. While doing the research, I realized:

  • Syntax is like construction. You can watch both all day but it's when you get your hands dirty and pick up a tool, that things begin to click.
  • Much like generics, closures will bring a lot of new terms and concepts. I don't mean the notion of a closure, per se, but rather the implementation in Java.
  • Already there is a lot of discussion: most of it from hardcore syntax surfers who revel in the corner cases and possibilities. (And more power to 'em)
The upshot is: I wonder if there is an opening in the blogtomonous collective for a gentler introduction. Even easier (and quicker) than the Groovy example mentioned above.

Here's a quick look....

The Setup
  • The download is available via Neal's original post Be sure to read the JRL
  • If you're on Windows, you might want a tool like 7-Zip to open the ztar file
  • Define CLOSURES to be the main directory
  • Ensure that JDK 6 is in the path. The shell files in CLOSURES/bin are key, as they modify boot classpath to use the new stuff. Though I love Bash on Windows, I used straight Windows BAT files that were morphed from javac and java in ~/bin.
The Gist

I'll assume that you're familiar with closures from Groovy, Ruby, Scheme, etc. With respect to the Java syntax, the most important things to understand are the Closure Literal and the Function Type.

In essence, the Closure Literal is the closure body; a Function Type is an abstract data type, a generalization of the venerable T for Generics. The difference is that the Function Type specifies many types for a function: (1) the types of the parameters, (2) the return type, and (3) possible exceptions.

I know: ZZZzzzz. To the ExampleCave, Batman!


// SNIP: public static void main...

String bulletin = " Hello Closure! ";

// Below, think: Type varName = closure;
//
// where Type = Function Type = { String, String => String }
// varName = myEasyClosure
// closure = Closure Literal (i.e. _the_ closure)

{ String, String => String } myEasyClosure =
{ String a, String b => a + bulletin + b };

// The closure is built into a class with an invoke method.
// To use it, simply call invoke with appropriate parameters.

String s = "this ";
String t = " is cool";

String result = myEasyClosure.invoke( s, t );

// output:
this Hello Closure! is cool

As annotated above:
  • We have a closure called myEasyClosure
  • Just as a generic type gives us, well, the type of a generic class, the Function Type states the types of the entire closure. Gafter could ask to us write IT_TAKES_2_STRINGS_AND_RETURNS_A_STRING but mercifully we write { String, String => String }. It is vital to understand that syntax.
  • The Closure Literal echoes the syntax of the Function Type: { params => expression }. Note that it doesn't return anything.
  • The whole point of closures are free lexical bindings: e.g. the free bulletin variable. Though this example is silly, that's where things get cool.
Keen readers will note that Function Types also specify exceptions. Let's decide that our closure should check for null on the parameters, and throw an IllegalArgumentException if that contract is violated.

Here's how to express it:


// remember:
// FunctionType varName = closure;

{ String, String => String throws IllegalArgumentException }
myEasyClosure =
{
String a, String b =>

if( a == null || b == null ) {
throw new IllegalArgumentException
("null parameters not allowed");
}

a + bulletin + b // no return or semi-colon !
};
Two points here:
  • The Function Type looks complicated, but we simply added a throws IllegalArgumentException into the definition.
  • In both examples, note that the final part of the closure body is an expression.
That's it... It should be fairly easy to mock up these examples with the prototype. With that foothold, it is easier to understand the more complex examples and discussions.

Monday, October 22, 2007

Jargon Watch: PragProgged


PragProgged:

To joyfully convey a novel idea with respect to software development, only to discover, via research or conversation, that said thought is merely a variation of a concept already eloquently expressed in that damn book, The Pragmatic Programmer.

E.g. Cool, but my friend, isn't that the same theme as in that book? I think you've been PragProgged.


ps. A pox on your houses, Andrew Hunt and Dave Thomas! That's right: may you suffer plain old XML for the rest of your days!

Thursday, October 18, 2007

Thieves in the Temple: Vandals, Dragons and Warp Guns on the JVM


Here are some motivators for this post.

1. Wired recently featured a piece on a new game called Portal. (Be sure to check out the awesome illustration here!) Essentially, players have warp guns that can bend the laws of physics: the guns create entry and exit portals though which the players can jump/dive. I'm not a puzzle gamer but this one looks neat. And, hey, it wowed Valve.

2. At the recent No Fluff Just Stuff conference, Jeff Brown gave a talk on Groovy's Meta Object Protocol. It dawned on me, and perhaps others, that just because things compile to JVM bytecode doesn't mean that all things are equal. For example, if you add a method to a class using Groovy, what does it mean if you access it via Java? By the end of the talk, you could sense everyone struggle with these warp portals on the JVM. We literally had to warp -- er, wrap -- our mind around the multiple dimensions of bytecode.

3. Eric Burke recently posted some Java/reflection behaviour that he found surprising (in the spirit of the excellent book, Java Puzzlers, by Joshua Bloch and Neal Gafter).

All of this adds up to some recent experimentation with Java, Groovy, and the SecurityManager.

These examples use Java 1.5 and Groovy 1.1 RC 1. If you want to follow along, the CLASSPATH contains only the local dir "." and the Groovy jar, groovy-all-1.1-rc-1.jar.

No Warp: Straight Java

To add some fantasy to this article, the JVM is a Temple, which contains a Dragon. We are thieves and seek to capture some of the Dragon's breath, for immeasurable riches and formidable power. However we must elude the dreaded Gatekeepers, who stand vigilantly on guard. Here is a POJO:


public class Dragon {
private String catchBreath() {
return "essence of hot magic";
}
}

Clearly, with straight-up Java, the compiler prevents us from attaining the goal.

As Eric pointed out, we can do some reflection magic:


import java.lang.reflect.*;

public class PureJavaQuest {
public static void main(String[] args) throws Exception {
Method catchBreath =
Dragon.class.getDeclaredMethod("catchBreath");
catchBreath.setAccessible(true);
Dragon dragon = new Dragon();
System.out.println( catchBreath.invoke(dragon) );
}
}

This works fine. But if the Gatekeepers invoke the Spell of Java Security, we're stymied:


java -Djava.security.manager PureJavaQuest

Exception in thread "main" java.security.AccessControlException:
access denied (
java.lang.reflect.ReflectPermission suppressAccessChecks)
[ stack trace snipped ]

As an aside, the following security policy would allow us to succeed:


grant {
permission java.lang.reflect.ReflectPermission
"suppressAccessChecks";
};


Used like so (if the above were in my.security.policy):


java -Djava.security.manager
-Djava.security.policy=my.security.policy
PureJavaQuest

Warp One: Using Java with Groovy

Let's write a Groovy script to use the Dragon class directly:


println "Are gatekeepers using spell? "
+ System.getProperty("java.security.manager")

Dragon dragon = new Dragon()
println dragon.catchBreath()

Here's the run:


$ groovy EasyQuest.groovy
Are gatekeepers using spell? null
essence of hot magic

It works! I believe this is due to a bug in Groovy with respect to private access. (I'm ok with this because I suspect that it is a well-known issue that will be fixed soon). (Is this really a problem in Groovy 1.1 ? Am I missing something?)

Can we exploit this somehow? What happens if the Gatekeepers use the Spell of Java Security:


$ groovy.bat -Djava.security.manager EasyQuest.groovy
Are gatekeepers using spell? true
essence of hot magic

Hmm. The script implies that security is on, but it didn't seem to work. Though Groovy documents security here, perhaps I'm missing something on the setup. Groovy does sophisticated class loading and on-the-fly mojo. I suspect that it might be using a privileged block, and reaching that because of a mistake of mine. (If you know what I've done wrong, please comment or email me at codetojoy @t gmail)

Warp Two: Groovy to Java

Can we exploit this behaviour using Java? Here's the Groovy class that is effectively the same as the above script:


public class Quest {
public String engage() {
Dragon dragon = new Dragon()
return dragon.catchBreath()
}

public static void main(String[] args) {
Quest quest = new Quest()
println quest.engage()
}
}

Two steps: we use groovyc to compile Quest to a class file. Then, we'll warp and run it with java (with classpath as described).


groovyc Quest.groovy
java Quest
essence of hot magic

It works... Not really surprising, given the previous behaviour. Let's try it with the Gatekeepers' spell:


java -Djava.security.manager Quest
Exception in thread "main"
java.security.AccessControlException: access denied (
java.lang.RuntimePermission accessDeclaredMembers)
[ stacktrace snipped ]

Blammo. Busted by the Gatekeepers. Do you feel the warp here? A Groovy class is compiled to bytecode and run via the java command. Clearly Groovy's magic ultimately boils down to reflection, and Java Security cuts to the chase by simply shutting down the call, no matter from whence it originated.

Hyper Warp: Adding Methods

One more tactic... A standard trick for theft is to cause a commotion. Distract, then act.

With blatant abuse of the ExpandoMetaClass, we can do just that.

The ExpandoMetaClass allows us to add (or override) class methods in Groovy. Prepare to warp. The Temple is gonna get crazy.

If you look at the main() method below, it seems like an innocuous print statement. However, the static block is replacing the toString method for the String class. This commotion throws a NPE with the truly weird comment that the JVM has crashed.


public class Commotion {
static {
ExpandoMetaClass.enableGlobally()
String.metaClass.toString = {
->
String msg = "JVM crash. Contact sys admin"
throw new NullPointerException(msg);
}
}

static public void main(String[] args) {
String s = new String("All is well in the Temple");
println s.toString();
}
}

Game on. Bring it, Gatekeepers!

Here is the output, when run as Groovy:


groovy Commotion
Caught: java.lang.NullPointerException: JVM crash. Contact sys admin
at Commotion$__clinit__closure1.doCall(Commotion.groovy:6)
at Commotion.main(Commotion.groovy:12)


As it turns out, the behaviour is the same as Warp Two: when compiled to bytecode, Java will throw the same nefarious error when run without the Security Manager (aka AccessContoller). With Java Security on, Java catches the reflection attempt.

Conclusions

Did we ultimately steal the Dragon's breath? To be honest, I don't think so: certainly not with the Java Security turned on. In pure Groovy, there are either some bugs or perhaps my configuration is not quite right (I'll report as soon as I find out what is going on.)

Also, remember that we had a Groovy jar (the big, embeddable jar) in the classpath. So things aren't quite as 'fluid' as these output snippets may imply.

What we have done is seen the power of Java Security and, hopefully, bent some holes in your perception of the JVM.

Finally, all experimentation aside, we should strive to be Gatekeepers.

But beware: there are thieves in the Temple. And they have warp guns.

Wednesday, October 17, 2007

Grok Like an Egyptian: The Weirdest Language


These days, it seems that the older languages are new again.

Lisp, Smalltalk, and Erlang are getting a lot attention (yes, they are all much different in age).

I have wondered if another language would be brought out of the attic, and sure enough, it is getting some attention.

I'm talking about APL which is easily the most strange, wonderfully weird language I have ever used (though it has been years).

Consider this:

  • It required a special keyboard, and uses characters that are not ASCII. It uses a highly symbolic, mathematical syntax that has been compared to hieroglyphics.
  • From what I (vaguely) remember, no explicit loops or conditionals.
  • It is common to combine functions using higher-order operators in manner that is so terse, it makes Perl look like English. Think I'm kidding? How about a one-liner that computes Conway's Game of Life.
  • Kenneth Iverson won a Turing award for his contributions (of which APL was a major part).
At the risk of alienating the small, rabid crowd of APLers, I should point out that APL does not run on the JVM (to my knowledge), does not form the basis for a popular web framework, and may not introduce Java people to new constructs such as closures and DSLs.

But if you are looking for a new way to think about problems, this is a fascinating option.

Which leads me to a question:

Is there a good, free APL development environment for Windows?

I've been looking for one for some weeks now, but haven't really found anything. Help!

Time permitting, I'd be interested in getting back into APL and possibly blogging a bit (if I can render the character set on here).

Happy 9th, Bug 4152790

A colleague pointed out this bug, as filed against the JDK.

A Happy (belated) 9th to Bug 4152790! (Check out the comments)

Delightful...

This is not a campaign to fix this bug, btw. Just an appreciation for benevolent wit. Though one can imagine that this one might be frustrating. I wonder how much, if at all, the "danger threshold" for the size of the graph/stack has changed across JDKs. e.g. Java 1.3 versus Java 6

Wednesday, October 10, 2007

Exposition as Genius

Recently, a colleague stated an eloquent view of genius:

An accomplishment is not truly ingenious if the person cannot explain it.
I love this quote, vis-a-vis software:
  • If one considers code as an explanation of what the computer is doing, then this quote has inherent disrespect for clever hacks and tricks.
  • More generally, a good, thoughtful explanation is quite an accomplishment, and a gift: it requires articulation, respect, and an intuitive feel for the audience. Over my career, I have learned that a critical attribute of a work environment is: do I feel comfortable asking questions? This spans technology and domain knowledge.
  • This quote says nothing about the creative spark or _how_ the person came up with the idea. That's a separate issue, and a tall order. I doubt that Mozart could tell anyone how he wrote; i.e. how his genius worked. But he could tell you why a particular piece of music works.
Great stuff.

Pathological Development (The World According to Garthe)

Alex Miller has an interesting post on the concept of the Garthe JVM. Named after the evil twin of a TV show protagonist, the Garthe JVM would support the Java Memory Model but be otherwise evil (e.g. nefarious thread scheduling and bytecode re-ordering).

An entire JVM isn't realistic for me (those Terracotta guys aim high), but the notion of injecting some evil into your project, for testing, can be really illuminating, and even fun. (Note: this is app testing, not testing the memory model semantics.)



The Original Pathogen

Many moons ago, I worked on a web project that used a home-grown HTML templating framework. This was pre-JSP, but they used macros which were a precursor to JSP taglibs. The dev team had one pathological macro that would explicitly throw an exception. Needless to say, it was undocumented.

However, it was very useful. The app was in C++ so memory leaks and exception safety were key concerns. When testing for these factors, one shouldn't wait for evil to happen: one has to be evil. One has to be Garthe.

Garthe Injection

These days, with IoC containers and mock testing objects, there are variety of tools that one can use to inject some pathological behaviour into an app.

How about this world, according to Garthe:

  • an implementation of a ORM layer where the DB goes down every 5 minutes
  • network latency is most definitely not zero in Garthe's world: it can be infinite, and there are network-based objects to prove it
  • an exception of some type T really are thrown from strange corners of the design
  • a homegrown (undocumented!) Swing/UI component creates its own thread and attempts to process UI events on that thread, and not on the EDT
Madness, you say! What evil behaviour!

Precisely: how does your app handle it? If you asked the team, just as a thought experiment, would they know? If Person A and Person B have different speculations on the outcome, what does that mean?

This pathological development is a great conversation starter, and in terms of role play, it's fun. Just be sure to mark the code very clearly or, better yet, have a "skull and crossbones" jar/project that contains the source.

Sunday, September 30, 2007

NFJS 1 Boredom 0 (a No Fluff Just Stuff review)

Here's a disclaimer from my review of March 2007:

This is
NFJS #6 for me. The first 4 years, I worked with a previous employer. This year, I attended while employed by an affiliate of a sponsor. Over 5 years, I have paid some of my own $; other times, an employer covered the cost. All 6 times, my own, personal weekends were consumed. As you know, these opinions are solely mine.

The Skinny

If you are new to NFJS, see my review from March 2007 for a general overview. This review will assume you're familiar with the shows and are interested in the current 'vibe'.

The upshot, like last time, is that this is a no-brainer if your company will foot the bill. If not, then it is a personal decision. I believe it is a good value, and am glad I attended. I felt it was a weekend well-spent because:

  • I love the energy from a concentration of developers.
  • Though the show is more familiar now, and one can't recapture the wide-eyed wonder of seeing these speakers for the first time, the content is topical and good stuff.
Plus, it's fun.

Editor's note: In this CodeToJoy exclusive, Jay Zimmerman (organizer), Ted Neward (keynote speaker), and a computer (Ted's infamous Mac) report the result of the weekend:



The Vibe

From my perspective, the prevailing themes of the show were:
  • The energy around the Language Renaissance is palpable. Everyone wants to try out at least one of Scala, Erlang, Haskell, etc for fun. To paraphrase panelist Jeff Brown: Groovy and Ruby are now required. (Ed: see Jeff's clarification of context in the comments. 'Twas a fun remark that got a big laugh, though IMHO it is a reasonable statement.)
  • Both open-source solutions and agile methods are increasingly accepted in the workplace. The level of discourse is much different than even 2 years ago.
  • Yes, the buzz around Rails and Grails is still strong. Increasingly, speakers are talking about making money by working on these kinds of projects.

The Keynote

Ted Neward talked about how the next 5 years will be about languages. (Fellow speaker Alex Miller has a post which contains a link to a similar talk and some of his own commentary).

Ted's thesis was that the Big Runtimes (the JVM and CLR) act as a bridge between the academic language lawyers and the problem solvers in the field: the academics can experiment with language syntax and exotic semantics; the problem solvers can use these languages and rely on the venerable runtime libraries to get things done.

I enjoyed the talk thoroughly. Ted paced to-and-fro like a giant cat: if NFJS is Narnia, then Ted is Aslan, except very hungry, and with a mild-case of rabies. Many good jabs toward, well, everybody. He's an equal-opportunity offender (and a big softie underneath it all.)

Editor's note: In this shot, the popular veteran speaker Stuart Halloway concurs with the result:



The Panel

The panel discussion (during a lunch break) covered the language issue, and the Rails/Grails progress, but also discussed:
  • Is the JCP a good thing? e.g. Should Spring go under a JSR? Would it have succeeded if it originated that way? (Opinions were mixed: many agreed that the JCP has done cool things, particularly for language development (e.g. annotations), but most think it is too bureaucratic to have spawned something like Spring).
  • Sun goes open-source with the JDK/JVM: good or bad? There was disagreement on whether or not there would be forks, but most felt this wouldn't be harmful.
  • A favorite is the panel's picks for tools and books. I'll try to summarize the books in a future post. Major props to the seminal JCiP and many 'psychology of design' books.

The Sessions

I can't cover them all or even half, but some memorable sessions for me:
  • Jeff Brown had a very cool session on Metaprogramming in Groovy. I have some experience with Groovy, so it all just clicked for me (e.g. the ExpandoMetaClass). I think that this is strong mojo, and probably best used in frameworks (versus apps). But it's powerful... I am planning a post on the effect of mind-bending warps through the JVM as one 'thinks' in Groovy and then in Java.
  • You can't go wrong with Stuart Halloway: I saw at least 2 sessions on agile development. The pace is animated and brisk; sometimes it's like doing mental wind-sprints, but the ideas just flow.... One takeaway was that Stuart's company really, really does agile in a major way. How about this: the CI build breaks if it detects that the 'code complexity' constraints are violated. Here's a thought: comments often describe what the code is doing, but the code should really be so expressive that it describes what the computer is doing.
  • I caught a session on Terracotta caching for Hibernate with Alex Miller. Highly recommended. I don't know a lot about clustering, but there were demos and stats that were made the case in a compelling fashion. I'm still blown away by the very nature of Terracotta. I thoroughly enjoyed getting to hear Alex talk about it and some of the internals. I recommend keeping on eye on this project.
  • Michael Nygard won me over during the panel discussion, and created some after-session gossip. That is, he told stories about enterprise failures (often involving holiday online sales), and, later, people would share these nuggets like ghost stories around the campfire. I saw his talk on 'Design for Operations'. The gist was that developers aren't done when QA gets the deliverable: it goes into production. Yet it is amazing how corporations act as though Dev and Ops are 2 entirely separate, disjoint entities. The thought is that there are a variety of ways to get them closer together: true person-to-person communication (!), and designing for monitoring (e.g. JMX) are just two examples.
Final Score

At NFJS #1, I saw Dave Thomas for the first time. I heard my first "Ted Neward Insult Of Irreverence". One can't recapture that kind of magic, which was kinda like geek sex.

NFJS #6 was a different kind of experience, but because now _I'm_ different and the 'speaker circuit' is more familiar. It was a fun weekend and worth the investment.

If I hadn't been there, I'd either have been on a treadmill or watching a baseball team which has already missed the playoffs. There's no contest:

NFJS 1 Boredom 0

Raw Cookie Dough from NFJS

I just came out of the weekend conference at the No Fluff Just Stuff/Gateway Software Symposium.

I hope to post a review later, but first here are some fun quotes and 'half-baked' thoughts that I had during the show. Some of these ideas may become future blog posts; they are 'half-baked' not in the sense of crazy, but 'not fully-cooked'.

Quoteth (actually: paraphraseth)

  • I think the Macs are good, but the experience is oversold. -- a Mac owner (Hallelujah!)
  • Best practices are average practices, because everyone does them. -- Stuart Halloway
  • An enterprise app has two sets of users: end-users and operations staff. -- Michael Nygard
  • That pen extends Throwable. -- Brilliantly witty attendee commenting on Ted Neward's penchant for throwing pens during keynotes
  • Scala, Erlang, and Haskell should be on your list for experimentation, and, well, Groovy and Ruby are simply required. -- Jeff Brown (Ed: this was a wry remark in jest, see Jeff's comment on the review post).
Half-Baked Cookie 1: What is 'Slow' ?

I wonder if there are any studies in cognitive psychology or neuroscience that offer insight into our perception that a computer experience is slow. It seems that as computer scientists, we have a wealth of empirical evidence and tactics (e.g. make a home page for website ultrafast), but what do the brain people have to say?

Half-Baked Cookie 2: Latency _is_ zero

Ted Neward mentioned that we repeatedly fall into the trap that distributed computing is easy: latency is zero, the network is reliable, and other Big Fallacies. It seems to me that part of this problem is that as developers, we optimize our work environment so that these fallacies are true. e.g. We write mock unit tests so that we don't have to suffer the inconvenient network; if we manually test an app on a network, we scream blue murder that our internal network is slow.

It makes sense that we want to develop software without obstacles, but we build an ivory tower that is far removed from the network. This Development-Production Gap is why we fall into the trap over and over again.

Half-Baked Cookie 3: Observing Software in the Wild

Based on a cool presentation by Michael Nygard on Operations in the enterprise, I think that a dev team should have a monthly review of log files from a production machine. There will be surprises and warnings of future trouble.

Half-Baked Cookie 4: JVM Decorators

Though I prefer the term 'JVM Tunnelers', there is an argument that many of the new languages hosted on the JVM are implementing a macro-level decorator pattern (of sorts) for the JVM. The JVM (and libraries) are still there, but there's now a lot of syntactic window dressing (and ideas) on top.

Groovy is to Java, as BufferedFileReader is to FileReader ?

Half-Baked Cookie 5: Packets in the Wind

Whenever 4 or more developers discuss real life while dining, one (often me) has to draw a parallel to computer science. This is especially true for traffic patterns in St Louis and networking analogies (often broken routers and YouTube saturation).

Half-Baked Cookie 6: Security Manager as Code Police

Ted Neward talked about using the Java Security platform to enforce that a webapp is not able to call System.exit() (which would be, um, bad).

I wonder if this can be extended to other code, during CI builds/unit testing. Assume that there is a class/method in your project that you don't want others to call. Perhaps Spring or something demands that a setter is public. Does it make sense to use a security policy that would fail CI if that contract was broken?

Half-Baked Cookie 7: Ruby Evangelism

Stuart Halloway mentioned a fact that is well-known to NFJSers. Dave Thomas deserves a lot of credit for the Ruby Rage. For years, he has spoken at NFJS (primarily a Java conference), and has proudly proclaimed that he doesn't know Java. He was (and is) an old-time preacher going around from town-to-town, literally, and conducting powerful sermons on the redemptive powers of Ruby.

It worked. Before RoR, there was Dave T.