Saturday, April 10, 2010

Guava as an OSGi bundle


I have published an update site that hosts Guava (which hosts some of Google's core Java libraries), as an OSGi bundle for you to use in your Eclipse projects.

Before you use the update site, keep in mind: There are some kinks that need to be worked out. For example, it seems I didn't get source attachment right, and I'm keeping the version numbers low until the process runs more smoothly. But more important, URLs are going to change, so it is not a reliable site yet. Only use it to test and provide feedback on the set-up.

Feedback is welcome, but patches and (OSGi/Subversion) guidance will get priority over requests.

The update site URL is at http://guava-osgi.googlecode.com/svn/trunk/com.google.guava.site/. It's got the r03 release, which contains the first binary distribution of Guava.

Thursday, April 08, 2010

Thought Experiment: First Response

Give the answer that first comes to mind:

Someone says to you: "I want your opinion. I hate the way [some computer language] handles [some problem] and I wrote a really ugly hack to get around it."

What's your first reaction?

a) You want to help the person solve his problem
b) You want to know the hack

Saturday, April 03, 2010

Controlling the Kokokaka Interactive Piano

Here's some fun I had with an afternoon hack session.

The start

To start, look at this video. Play with it. It's an interactive piano. Wait for the whole video to load, and then click the piano keys with your mouse. You'll see that clicking a key moves the video's position to the spot where that note is played. In other words, you get to play the piano on the YouTube video by clicking keys.



That was fun; I wanted to automate playing the piano with a script. Could I do it? Well, yes. For the most part.

Controlling the Mouse

This turned out to be rather difficult, and in the end I could not get it quite right. But it's good enough.

Since this was a Mac workstation, I assumed it would be an easy matter to get AppleScript to do this, but I gave up after about 45 minutes of trial and error. I couldn't even find an API, let alone a reliable one. (This also included a short foray into experimenting with the Automator. Nope, it wasn't going to work.)

I finally found an answer on Mac OSX Hints with a full example of how to build a command-line binary that positions and clicks the mouse.

The secret sauce of this example was the Quartz Events method CGPostMouseEvent.

Did it work? Yes. No. Not really. Calling ./click -x x -y y certainly sent the mouse to the correct position, but it didn't seem to actually generate the correct click event. Do you know what worked instead? Calling it twice. Yep.

./click -x x -y y ; ./click -x x -y y works.

Most of the time.

I tried all sorts of things, like creating delays in between the clicks, or delays between the mouse-down and mouse-up events. No luck. Anyway, this was the simplest correct solution. That's what they call elegance, you know: the simplest, correct solution. Doesn't feel like it.

I noticed CGPostMouseEvent was deprecated and replaced with the pair of methods CGEventCreateMouseEvent and CGEventPost. I replaced the code with the newer methods, which resulted in no reasonable change to the application. But I didn't switch back.

The major problems with this solution were not only that there could be a risk of skipping, it also, the browser seemed to get overwhelmed by these fake mouse events, enough so that the video would stop playing. The mouse click events would continue to be delivered, and the video would be repositioned in time to the correct spot, but the video was paused; so no music came out. The faster the music played, the more likely the video would halt. Too bad.

A final comment about mouse control. I found that this only worked with Safari. It didn't work well (or at all) with Firefox or Chrome.


// File: 
// click.m
//
// Compile with: 
// gcc -o click click.m -framework ApplicationServices -framework Foundation
//
// Usage:
// ./click -x pixels -y pixels 
//
// additional data found at
// http://stackoverflow.com/questions/2369806/simulating-mouse-clicks-on-mac-os-x-does-not-work-for-some-applications

#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>

// Read more: http://www.faqs.org/faqs/unix-faq/faq/part4/section-6.html#ixzz0k416qomt

int main(int argc, char *argv[]) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSUserDefaults *args = [NSUserDefaults standardUserDefaults];

  int x = [args integerForKey:@"x"];
  int y = [args integerForKey:@"y"];

  CGPoint pt;
  pt.x = x;
  pt.y = y;

  CGEventRef evt = CGEventCreateMouseEvent(
      NULL, kCGEventLeftMouseDown, pt, kCGMouseButtonLeft);
  CGEventPost(kCGHIDEventTap, evt);

  evt = CGEventCreateMouseEvent(
      NULL, kCGEventLeftMouseUp, pt, kCGMouseButtonLeft);
  CGEventPost(kCGHIDEventTap, evt);

  [pool release];
  return 0;
}

Finding positions

Now I had a relatively reliable procedure for generating mouse click events. Where should I click the mouse?

This was easy to solve. I put the browser in the upper left corner and used Grab to get a shot of the full screen. Then I loaded the image in Gimp and used the cursor position indicator. Given a full screen snapshot, the cursor position on the loaded screenshot image would correspond with a mouse position click event.

From there I could generate positions on the display that, when clicked, would generate the correct results.


my %points =  (
    toggle => [18, 580],
    c => [20, 500],
    cs => [40, 300],
    d => [80, 500],
    ds => [120, 300],
    e => [140, 500],
    f => [220, 500],
    fs => [240, 300],
    g => [280, 500],
    gs => [320,  300],
    a => [360, 500],
    as => [400,  300],
    b => [430, 500],
    C => [500, 500],
    Cs => [530, 300],
    D => [560, 500],
    Ds => [610, 300],
    E => [620, 500]
  );

Scripting the result

Coding up the controller wasn't very hard. I went through several versions, and settled on this:

#!/opt/local/bin/perl

use strict;

# system("gcc -o click click.m -framework ApplicationServices -framework Foundation");

my $tempo = 1;

sub _nap ($) {
 select undef, undef, undef, $_[0];
}

sub nap ($) {
 _nap($_[0] * $tempo);
}

sub note {
  my ($x, $y) = @_;
  system("./click -x $x -y $y");
  _nap .05;
  system("./click -x $x -y $y");
}

my %points =  (
    toggle => [18, 580],
    c => [20, 500],
    cs => [40, 300],
    d => [80, 500],
    ds => [120, 300],
    e => [140, 500],
    f => [220, 500],
    fs => [240, 300],
    g => [280, 500],
    gs => [320,  300],
    a => [360, 500],
    as => [400,  300],
    b => [430, 500],
    C => [500, 500],
    Cs => [530, 300],
    D => [560, 500],
    Ds => [610, 300],
    E => [620, 500]
  );

sub play($) {
  my @notes = split(/;/, $_[0]);
  foreach my $note (@notes) {
      my ($key, $duration) = split(",", $note);
      $duration = 1 unless defined $duration;
      print "$key-$duration- ";
      my $rpoint = $points{$key};
      print "$rpoint ";
      my @point = @$rpoint;
      print @point . $point[0] . $point[1] . "\n";
      note @point;
    nap $duration;
  }
}

sub scale {
 $tempo = .3;
 play ("E;Ds;D;Cs;C;b;as;a;gs;g;fs;f;e;ds;d;cs;c");
}

sub test() {
 $tempo = .2; 
 play ("c;d;e");
}

sub test2() {
 $tempo = .1; 
 play ("E;c;Ds;cs;D;d;Cs;ds;C;e;b;f;as;fs;a;g;gs");
}

sub twinkle {
  $tempo = 1;
  play("c;c;g;g;a;a;g,2;f;f;e;e;d;d;c,2");
}

sub fur_elise {
  $tempo = .5;
  play(
  "E;Ds;E;Ds;E;b;D;C;a,3;c;e;a;b,3;e;gs;b;C,3;e;" .
  "E;Ds;E;Ds;E;b;D;C;a,3;c;e;a;b,3;e;C;b;a,4;" .
  "b;C;D;E,3;a;f;e;d,3;g;E;D;C,3;f;D;C;b,3;e;" .
  "E;Ds;E;Ds;E;b;D;C;a,3;c;e;a;b,3;e;C;b;a,4;");
}

my %songs = (
  scale => \&scale,
  twinkle => \&twinkle,
  test => \&test,
  test2 => \&test2,
  fur_elise => \&fur_elise,
);

my $song = $ARGV[0];
print $song;
my $rsong = $songs{$song};
&$rsong();

Notice that _nap is actually a call to the Perl builtin method 'select'? It's a bit of a hack I read about in a couple of places; this is one.

The final result

Did it work? You tell me!



Success!

Parting thoughts

It's too bad there was no easy way to get a reliable mouse click on the Safari browser. That would make such a difference.

Collecting this data from a script feels a little cheap. I'd much rather have a keyboard send events that control the video. Anyone who has a spare electronic keyboard and a couple of hours of spare time, let me know.

Friday, April 02, 2010

Uncle Bob Martin - EclipseCon 2010 Trip Report



These are the roughly unedited notes from the Thursday keynote from EclipseCon: Uncle Bob Martin on  Software Professionalism and the Art of saying "No"


There are lines you will not cross. We may make lots of compromises, but there are some lines you will not cross.

First, do no harm to the function of your software.

But you may introduce bugs, what about that? Doctors manage to swear this oath. Can they pull it off? No, sometimes they screw up and so do we, but it's a good target to hit. I may fail but I'll do the dilligence necessary to make sure my code works.

That means we're responsible for our imperfections. And we take responsibility when we do do harm to our software.

QA group is absurd. QA should FIND NOTHING. Why do we have a QA group? Because developers weren't doing their jobs so we had to create a whole new group to find their bugs! How did we get in a mode where we lost responsibility for our quality.

QA role should change completely, instead of being at the back of the process, have them at the front of the process, specifying what the quality criteria to be.

You do not release code until you know it works.

Manual tests are desperately expensive.

I'm not expecting that you will achieve 100%, I will demand that you achieve 100%.

Do no harm to your code

People do not want us to write software that is hard to change. There is an implicit assumption that software is easy to change. It is incumbent upon us to make sure software is easy to change.

There are two values of code, one is its function and another is its structure, its value to grow and change.

"Yeah, but they won't give us time." Baloney! That is your problem, not theirs.

How do you make software that is flexible?

Design and architecture are not the only keys to flexibility. Software must be flexible. To make sure your software is flexible, you must flex it.

Nothing makes code more flexible than a suite of tests.

Professional developers are not afraid to change their code under any circumstances because they rely on their tests.

Managers say "We want these kinds of people." But that allows you the right to say 'no.'

There are a whole bunch of things you can say 'no' to. One of those is schedule.

Manager says "Wait, you can go faster if you don't write all those tests."

You say "No, you can't go faster without those tests. We go faster with those tests."

"You can go faster without design on architecture."

"You can go faster without refactoring" -- "You can go faster when you can refactor your code."

The worst thing you can say when your manager pushes on you is "Well, we'll try." There is no trying.

HOPE is the project killer. Hope keeps managers from making the decisions they need to make. Hope keeps developers from being fruitful. It is your job as a professional is to destroy hope. One way to do it is through short iterations. Measure in continually shorter cycles in order to see how much progress you can really get done.

The agile process is not about people, it's about finding out how long it takes small projects to get done. It is a HOPE destroyer.

Say No To Dirt.

Bad code got written because a bunch of bad develoeprs thought it was their job to make the most hideous mess they could make in the shortest amount of time. How that mess got made I don't know but you have to get rid of it!

There is a meme: "We have to get to market, so get the code done quickly. Keep your code as clean as possible all the time." Our mothers tried to teach us this.

The only way to go fast is to go well. Anything worth doing is worth doing well.

Say no to dropping your disciplines.

Say no to your manager, but really, say no to yourself. You're the one that you have to say no to.

You know what your discplines are when you are under the gun. And when you abandon what you do under stress are your true discplines.

Say no to overtime.

I'm not saying don't work overtime, it's good to work some overtime. But you should know your limits. But when your managers enforce overtime, you have to know your limits. You have to be the one to stop yourself.

Say no to meetings.

Managers it is your job to keep your people out of meetings. Meetings are the bane of productivity at companies.

The instant a meeting gets boring, leave. I exercise that right, and I encourage you to do so too.

Say no to dumb restrictions on your development environment.

Who is working in a place where you can't bounce a process? (no changes to a development database?) Engineers need complete control over their environment. You should have absolute control over your environment. You should have absolute control over your facilities?

What does "Saying No" mean? 

You make your argument energetically. And then you work with your manager for some acceptable compromise.

EclipseCon 2010 Trip Report


I'm finally caught up on email, and can take a chance to thank everyone who was responsible for EclipseCon's success this year.

If you're just looking for the slides from my talk, have at 'em.

There were too many talks and too many conversations to list them here. So here are the highlights.

Contents
  • Monday (Working with OSGi, The Ribbon IDE, What's New with JDT)
  • Tuesday (Keynote: Oracle, JDT Fundamentals)
  • My talk: Eclipse in the Enterprise: Lessons from Google
  • BoF: Eclipse in the Enterprise
  • Wednesday (Keynote: NASA, Building e4 Plugins)
  • Thursday (Keynote: Uncle Bob Martin, Understanding Git at Eclipse, Vendor Booths: UI Testing, Vendor Booths: Microsoft)
  • Eclipse Day at the Googleplex
  • Feedback to the Conference Organizers
Monday

I love tutorial sessions. Working with OSGi: The stuff you need to know finally convinced me that services have a place in my bag of tricks, particularly because they explained that ServiceTracker is as evil as I thought it was. (Go declarative services!)

I was happy to see people taking some practical approaches to the overwhelming nature of the Eclipse IDE. The Ribbon IDE - a leaner, modern UI for Eclipse shows what's possible from an evolutionary perspective (rather than the revolutionary ideas like Code Bubbles) but I don't see The Ribbon IDE needs work, which the presenter admitted.

What's New in JDT? Not too much, I'm afraid. Some small stuff that's nice, but nothing that gets me out of my seat yelling bloody hallelujah. This isn't the fault of the presenters, there's only so much a small team can do. How about this: every year, What's New in JDT should take at least an hour, and be crammed full of new stuff that makes users and plug-in developers super productive, even more than the previous year. But this starts to touch on a larger issue which I won't go in to just now.

Wait a minute, did I just praise Eclipse for being evolutionary in one paragraph, and then admonish them for the very same thing in the next paragraph? Yes I did. I can do that because I'm a non-journalist blogger-hobbyist.

Tuesday

Keynote: Community and Adaptation: It's good to see Oracle participating in EclipseCon. They really didn't teach me anything new, but they were a polished pair of professional presenters.

I missed much of Tuesday preparing for my talk.  My coworkers attended the JDT fundamentals talk, something I've attended in the past. It's a great talk. Fortunately I got a minute with Oliver who explained something unexpected: if you create an Eclipse Java project, and already have class files built for code in your project's source folders, copying the class files into the source folders' output directories is a fine way to bootstrap your project and eliminate some double-building. The class files built by the JDT don't embed special Eclipse metadata.

Eclipse in the Enterprise: Lessons from Google
This was my talk. Terry was supposed to give it with me at first, but given the short amount of time, it made sense to dispose of what might be a microphone hand-off.

My guess is about fifty people attended the Eclipse in the Enterprise talk. People have asked for the slides; here they are.

I apologize for not leaving more time for questions. The 25-minute limit worked, but only by cutting it kind of close. If you still have questions, let me know.

BoF: Eclipse in the Enterprise: Lessons from You

This was the accompanying BoF session where other folks who had similar issues to ours could share their problems and solutions.  About 25 people showed up to this one-hour discussion about how everyone else deals with large Eclipse installation issues. You could feel the camaraderie when it came to some similar issues around support, scalability, and managing OSGi.  I took some notes, but I have to admit they only discuss high level topics, and are not very useful.

I did try to copy down the list of all companies that attended the BoF:
  • EclipseSource
  • JP Morgan Chase
  • SAP
  • Eclipse Foundation
  • Google
  • eBay
  • IBM
  • Ericcson
  • Netcetera
  • (If I missed you, feel free to drop me a line and I'll augment this list.)
One noteworthy thing: UDC. Nobody really uses UDC, though one person knew how to redirect UDC output to their own servrer, and append it with specialized information. Some of that information was passed around by email after the fact.

Wednesday

Keynote: Rocket Science and the Republic: Jeff Norris' keynote was the only one I missed. It was the morning after my talk, and I celebrated that night just a little too much and opted to sleep through the talk.  Ian Skerrett called it the best keynote ever

Building e4 Plug-ins: Interesting. The tutorial gave me a sense of just how different e4 is from the 3.x stream. It's clear that 3.x is going to be around for a LONG TIME (to support TV sets and what not) while e4 will support Java 5 and on. The takeaway: don't judge e4 by using the UI, judge it by using the API. Oh, and running their tutorial on OSX was wonderful. By wonderful, I mean, didn't work at the last step. Wah.

Thursday

Keynote: Software Professionalism and the Art of Saying "No" by Uncle Bob Martin. What a great presenter. I took some good notes, and was left with all sorts of ideas. Those notes are published as a separate post.

Understanding and Using Git at Eclipse: Great tutorial. I'm ready to start using Git. They managed to keep much of the Eclipse part of Git until the end, which meant us non-contributors got plenty of value out of the talk. My android appreciated getting out of the hotel room to learn about git.

The last talk I attended was Mylyn Reviews - Finding a new Home for ReviewClipse. I love how Google's code review process makes me a better engineer. Anything that will help elevate software development from a being a group of individuals to a team of individuals gets my support.

Speaking of Mylyn, one of the Tasktop employees told me that people blaming content assistance timeouts on Mylyn are "shooting the messenger". According to the engineer, the timeouts are purely due to JDT, but the error dialog mentions Mylyn, so people assume that's the case. I have coworkers that have removed Mylyn because of this. I'll keep this comment in mind the next time such a support issue arises.

Thursday was my opportunity to finally view the vendor booths. I went to most booths that boasted automated testing tools. Once again, I'm still not convinced that there's a good UI testing tool that would solve my integration test problems in a way that integrates with our development process. That isn't to say the development process can't adjust, nor is it a reflection of UI testing tools in general. There's one I would like to play with in the near future, though. It would be inappropriate to mention it here.

Microsoft was there, both as a vendor and presenter! They've been there before, but I find the Eclipse / Visual Studio integration concept fascinating. I'm sorry for not really putting in the time required to understand it, as well as the opinion of an engineer intimately aware of both products.

Eclipse Day at the Googleplex

Many of you asked about whether Eclipse Day at the Googleplex would be repeated next year. Thanks very much for your interest. If it happens I promise to let you know.

Feedback for the conference organizers
  • This morning I was reviewing the site to find the speaker agreement I electronically signed, but could not. Next year would you please email a copy of the speaker agreement upon approval?
  • 25 minutes for most talks. Turns out that worked for me, rather well. From a personal perspective, it took a lot of time to cull my talk into the 25-minute period but in the end it worked just fine.
    • At the same time, speakers must realize that while their talk is listed as a 30-minute block of time, they are not entitled to speak for 30 minutes. They're also not entitled to speak for 25 minutes. They're entitled to a 25-minute block of time, with time on both sides to set up, test, and tear down. Anything else disrespects, the next speaker and his attendees, and all your speakers, who don't want to be late for their next talk.
  • Special props to the A/V staff at EclipseCon. They were instrumental at helping me set up and test my equipment in advance of giving the talk, making the actual set-up very easy.
  • Breakfasts with cereal and fruit. Thank you. Very much.
  • Online program guide: please default the online program guide view to the current day. I don't want to see Monday's program listing by default, anytime after Monday, until the end of the conference.
  • I don't want to have to power up my laptop or phone to get presentation summaries. Sometimes there's only two minutes to choose a talk while shuffling between the rooms. Please provide printed summaries of the talk.
  • I liked having the conference right next to the elevator to the hotel rooms.
  • I look forward to next year's logo adopting the new brand identity.
Miscellaneous notes from the conference

Here's a sheet of notes I scribbled while at the conference. What do they mean?

  • Stars awesome.
  • FLASHBACK!
  • Credits list goes on forever.
  • Melinda Hsu Taylor
  • Greggory Nations
  • Tucker Gates
  • Lame accident
  • Whitfield
  • Property of Magnus Hanso!
  • GASP! The statue!
  • Better color for the crashed ship?
  • Black smoke loses its effectiveness now. Just the sound of the bad guy coming.
  • "It's good to see you out of those chains?"
  • Body switch?
  • Weak!
Oh, right I took these notes while watching Lost in my hotel room.