Java at MongoSF
As has come to be expected the 10gen-ers have put on a great conference. It's almost like a MongoDB world domination tour with the NoSQL Live in Boston this March, MongoSF and MongoNYC this month and MongoEU this summer. There seemed to be bigger numbers of Ruby and Python devs but that wasn't so surprising given that they tend be early adopters compared to Java devs. Because of that I believe the path to reach Java developers is to show them that they don't have to throw away all their code to use MongoDB. My morning session capitalized on that and used Grails to show how you could quickly wire up persistence using DAOs with Morphia and MongoDB.The afternoon session that was a bit more high level primer for what was covered in the morning.
Using MongoDB with Morphia and Groovy
As I mentioned in this post, I live coded a blog site using Morphia and MongoDB in my workshop session at MongoSF. I used Grails as the platform to quickly scaffold the application. One might wonder why I didn't use the Grails plugin. I used Morphia because it aligns with traditional Java paradigms and didn't want to have too many new items by using a full Groovy stack.
Setup
After installing MongoDB, you will need a version of the Java driver and the Morphia library. Make sure to use the latest snapshot.
Creating the mapped objects
Morphia uses Java annotations to describe how to persist objects in the database. The following annotations are available:
- @Id - marks the MongoDB id field to be autogenerated
- @Entity - marks the class to be persisted as an object and optionally the collection
- @Embedded - tells Morphia to embed this object in another
- @Reference - analogous to MongoDB DBRef
- @Indexed - prepare an index for this property
- @Serialized - store as BSON
- @Property - indicates that the property name in MongoDB will be different than in the object
- @Transient - doesn't persist the property
As you may already know, Groovy adds a few properties to objects. You will get an error that it won't persist the unmapped fields but it doesn't inhibit execution. Our BlogEntry class contains a title field, date it was created, content, a MongoDB document id and an embedded list of comments.
import com.google.code.morphia.annotations.*
@Entity
public class BlogEntry implements Comparable{
@Id private String id
String title
Date dateCreated = new Date()
String content
@Embedded
List<comment> comments = [ ]
}
Similarly, our Comment object contains properties for the name, dateCreated, and content. Please note that both places that refer to Comment need the @Embedded annotation.
import com.google.code.morphia.annotations.*
@Embedded
public class Comment {
String name
Date dateCreated = new Date()
String content
}
While you can marshal/unmarshal objects from POJO/POGOs to BasicDBObjects and persist them to a collection by hand, it is much simpler to use a data access object(DAO) which provides all the CRUD functions for you.
import com.mongodb.Mongo
import com.google.code.morphia.*
public class EntryDAO extends DAO {
public EntryDAO(Morphia morphia, Mongo mongo) {
super(mongo,morphia, "entries")
}
}
In this snippet, I initialize a DAO object, create BlogEntry and Comment objects, persist them to the DAO, and read them back out to prove they were stored. Please excuse the Java-ness of the code but I didn't want to blow people's minds with too much Groovy.
import com.mongodb.*
import com.google.code.morphia.Morphia
mongo = new Mongo()
morphia = new Morphia()
dao = new EntryDAO(morphia, mongo)
entry = new BlogEntry()
entry.setTitle("Test Entry")
entry.setDateCreated(new Date())
entry.setContent("This is a test entry.")
comment = new Comment()
comment.setDateCreated(new Date())
comment.setContent("Test comment")
entry.comments = []
entry.comments.add(comment)
dao.save(entry)
entries = dao.find()
entries.each {
println it.properties
}
With a running instance of MongoDB, you could run all these bits in a Groovy console and see it in action. In the next post, I'll cover how to integrate these classes into a Grails application.
The book that was not to be
Some of y’all might have noticed that my blog has been relatively silent this summer and spring. While some of this can be explained by summer vacation, there was another major reason.
I was writing a book. On Google Wave. Yes, that Google Wave, whose development was suspended earlier this month. I lucked out in that I only had four chapters completed. Others weren’t so lucky. A Wave team member I met at the GTUG campout told me that a Japanese book was released on the same day as the announcement.
Thrust in this situation, you could be mad about what could have been or roll with it. I am happy about is that I didn’t announce it too early. If I had done so, I think this experience would have been more embarassing fail than case of "que sera." I got to break the news on my terms. I learned a lot in the process and plan to share some of that in upcoming posts.
I still believe Google Wave is a great project and appreciate all the help I received from the Wave team, editors and reviewers. You might even see the fruits of my labor as smallish e-book(~100pgs were written). Don’t feel too bad for me, I have a new project that I will surface when the time is right ;).
How to get a tech book deal
Before the deal.
Blog and blog often.
A blog is your 24/7 writing portfolio. Pure and simple. It is also a place for you to hone your craft. If you can handle keeping up with writing blog posts for six to nine months, you MIGHT be able to handle writing a book.
Guest-blogging gives you a taste of what it feels like to deal with an editor. It’s a delicate dance where you fight for the things that you feel are really important and concede on the things that aren’t. Just like your editors for a book, the owner of the guest-blog wants the best product possible from you. It doesn’t even have to be on a technical subject. A guest blog spot is a great place to blog an interest that otherwise doesn't fit your regular blog.
The proposal.
Either you will contact publishers or as in my case, they will contact you. The first hurdle you’ll have to clear is the book proposal. This can be simple and include a couple paragraph pitch and an outline or it could be more involved requiring also a sample chapter and market studies to gauge competitors. Even if not required, at minimum you should do a market study to see what is out there, what their focus is, and how your book will be better...err different. Amazon.com will have most published books listed but you will also want to check InformIT, Apress, Manning, and OReilly to persue the chapter outlines of pre-release books.
After the proposal is tentatively agreed upon, you might be asked for a detailed chapter outline and schedule. Don’t skim on the outline. Getting as much on paper as possible early on helps you during those late night/early morning writing sessions. A chapter is not the same thing as a series of blog posts. Each has different constraints and requirements. Don’t think that just because you can whip out a blog post in a day that level of efficiency will be the same in writing a book.
Writing your first couple of chapters.
There are a few rare exceptions but more often than not, your publisher will ask you to use Word to submit your chapters. OpenOffice, Abiword, and I assume KWord work just fine but there is one important rule you must follow. Pick one editor and stick with it.* Since there are slight differences between how those applications create Word documents, creating a Word document in OpenOffice with tables and figures might get messed up when opening in AbiWord. It’s usually nothing major but nonetheless, having all your auto-numbered tables set to Table 1 is not exactly fun when you have a deadline to meet.
You never know when inspiration will strike. One of the other things I do is to carry around a notebook and pen with me. You can use it for impromptu outlines or sketching out ideas. To make sure you can work on your text wherever and whenever, setup a cloud sharing service like Dropbox or Ubuntu One. These services let you work from any computer and keep the files automatically in sync keeping all previous versions. That way you have no excuse to work on things and constantly have multiple copies in case of computer problems.
There is good reason that until now, I haven’t mentioned the money. That's because It ain’t really all that. You might make more in a paycheck than the total amount of the advance. The big payoff can’t be and shouldn’t be what continues to drive you in the project. The desire to share your unique voice should be. While fiction books can be timeless, tech books generally have the half-life of whole milk.
* Google Docs is not suggested at this time as it has limited support for styles.
IndexedDB features with Lawnchair
One of the projects I’ve been working on has lately me researching HTML5 DB standards. While I’ve been able to find SQLite-compliant browsers, IndexedDB has been a little more difficult to come by. I don’t know if it is the problem is that I’m on Linux or that I’m not getting the right nightly build of Firefox/Minefield.
After installing the latest daily build once again, I remembered the Lawnchair project. Lawnchair provides a client side JSON document store and is inspired by document databases like CouchDB and is written in JavaScript. The API is very different from IndexedDB but Lawnchair can provide object store capabilities in a layer above SQLite and also supports adaptor backends to store objects using domStorage or cookies.
Hopefully when IndexedDB is more codified, Brian LeRoux will extend it to provide a common interface just in case some browsers choose to never implement IndexedDB.
MongoSV 2010
Edit: Scott Hernandez, whom I was filling in for and one of the core Morphia developers, will be presenting instead.
The MongoDB world domination tour countinues with its return to Silicon Valley on December 3rd taking place at the Microsoft Research Silicon Valley in Mountain View. I'll be presenting "MongoDB with Morphia: Web Scale Java Development." For those of you who haven't seen the web video "MongoDB is Web Scale," the title is a self deprecating allusion to it.
StrangeLoop 2010
This year, StrangeLoop was a little more relaxed for me given that I had no sessions to present. Although it is exhilirating to present at a conference, sometimes it is just as fun to just be an attendee. The first session I went to was Ken Sipe’s session on Gradle. I’ll have to admit that I’m already a Gradle fanboy but it was nice to see Gradle coming along as a valuable component in the Java ecosystem. The next session I went to was VMs with Go presented by my friend Eleanor McHugh. I’ve really got to get started with coding Go. I’m really intrigued by the compile times.
Another standout was the Android Squared talk presented by Eric Burke and @crazybob, errr Bob Lee where they described the lengths they had to go through to get credit card signals over the microphone jack. If and when the video comes out, watch it. They also announced the opensourcing of a modular Android library called Retrofit. Retrofit has classes that simplify getting io, http calls, and shake events from Android devices. I’m looking forward to working it into some Android projects I’m working on.
Douglas Crockford’s keynote on Open Source Heresy was really good. That’s another video you should watch. In his talk, he describes how JSON came to be and how he didn’t wait for a standards committee to validate or approve his efforts. He just did them and let the market catch up to him.
One of the things that sets StrangeLoop apart from other conferences is StrangePassions. It’s part-party, part-geekout. The entertainment for the party are short sessions on interesting topics that CAN’T be programming related. This year there were talks about brewing your own alcohol, photography, politics, and the frequent crowd pleaser lockpicking. While we find common ground in being developers, things like StrangePassions gives us an opportunity to bond on deeper terms.
Mozilla Labs - Open Web Gaming recap - Part 2
The second half of the night had smaller scale demos and lightning talks. Jono, a Mozilla employee, showed a couple of demos. The first was based around the new touch events in the Firefox 4 beta. He used the touch events with a touchscreen netbook to create a web comic creator. The second was a tile map framework reminiscent of Zelda. He made a call out to the community to try and make it MMO with WebSockets. You can find more information about the events here.
Ari Bader-Natal presented on Studio Sketchpad, a mashup of Etherpad, the collaborative online document system and Processing.js, a 2D graphics library. Studio Sketchpad is interesting because it gives instant gratification. You can tweak an exisiting script and run it. No compilation or setting up a scaffold environment. Ari posted a video of his slides here. You can follow updates at @studiosketchpad .
Matt Claypotch, another Mozilla employee, showed a Labyrinth game wired to use orientation and acceleration events from the browser. You can check out the game here:potch.me/labyrinth. He also demoed a Canvas particle engine that could be used for explosions or gunsmoke, as on the Game On homepage.
The last preso of the night was on Mozilla Rainbow, an addon that exposes a JavaScript API to the webcam and microphone to allow recording audio and video. At the moment, only OS X is supported but Windows and Linux support should be forthcoming.
I am writing a book
Back in August, I talked about a Google Wave book that seemed not to be. I expressed hope at the time that it would be able to be made in some shape or form. While the progress of Wave in a Box has been encouraging, I'm not announcing a new form for that material yet. I also mentioned a new project I would announce later...
Now is that time. I'm happy to announce that I'm writing a book for Addison Wesley on HTML5 Game Programming. The book is set to cover HTML5 Canvas, SVG, WebGL and other cool stuff. Java devs, don't be discouraged, I have some bits planned just for you.
The exact release date is not set but my guess would be sometime mid to late next year. I've got a couple of chapters in the can already and am working toward an early access release that should come out in the next couple of months. I'll keep y'all posted on that.
Creating a Twilio library in CoffeeScript
A library is only as good as its ability to get out of the way when you are coding with it. I decided to test the capabilities of CoffeeScript by using it to create a library for Twilio. I chose Twilio's Java library to port because it is expressly object-oriented.
constructor: (number) ->v = new VerbConstants()super(v.DIAL, number) if number isnt undefinedsuper(v.DIAL, null) if number is undefined@allowedVerbs = [ ]@allowedVerbs.push(v.NUMBER)@allowedVerbs.push(v.CONFERENCE)
httpclient = require "ringo/httpclient"class TwilioRestClientconstructor: (accountSid, authToken, endpoint) ->@accountSid = accountSid@authToken = authToken@endpoint = "https://api.twilio.com/2010-04-01/Accounts/#{@accountSid}"request: (path, method, vars) ->tryresponse = httpclient.request({method: method,username: @accountSid,password: @authToken,data: varsurl: @endpoint + path + ".json"})catch errorprint errorexports.TwilioRestClient = TwilioRestClient
var twilio = require("twilio/TwilioRestClient")// Makes a callvar client = new twilio.TwilioRestClient("<accountSid>","<authToken>",null);var response = client.request("/Calls","POST",{To:"15553241111",From:"15553241112",Url:"http://demo.twilio.com/welcome"})print(response.content)
Two days with the Chrome OS Netbook
It’s been almost a full two days since there was a major “Oprah moment” at the Silicon Valley Google Technology User Group meeting and I received a shiny new CR-48 netbook. All attendees were offered the chance to join the pilot program and other than agreement not to sell the equipment without Google’s consent, there aren’t any strings attached.
All and all, it has been a really pleasurable experience. It’s not quite fully baked but I didn’t expect it to be. The first thing you had to do when setting up the device was to enter your Google credentials and take a photo that would act as your login avatar. There’s a great chance you will look goofy or weird in the photo. Luckily there is a way to change that photo with a different one using Picnik.
Applications
Some companies have decided to make their Chrome Web Store application act as a simple bookmark to their web app and others like TweetDeck have made a new experience for Chrome which is much appreciated. One major difference between a regular desktop and Chrome OS is how it handles Google Talk. The collapsible chat windows float above the browser and they can be rearranged along the bottom edge of the screen. One of the issues in regular Chrome where you opened a chat window in GMail then accidentally navigated away from the page killing the chat is not longer a problem. Scratchpad is a built-in note taking app that floats above the browser and syncs to Google Docs. Seems like a welcomed retooling of Google Notebook. The other app I’ve used alot is Google Books.
Audio/Video
Despite the reviews about Flash, it has worked reasonably well for me with Youtube and other Flash sites. Netflix doesn’t support Linux and ChromeOS is Linux so that was an immediate no-go. If you buy movies and tv shows à la carte anyways, then Amazon Video on Demand fills the gap. Jaman is also a source for more indie content.
For music, I use a combination of Rdio and Jamendo. Both worked fine.
Video chat
I haven’t yet tried video chat in Google Talk but I was able to stream from the web cam in UStream. The web cam name is the “Mario cam”. LOL. It should work on any site that uses flash
Peripherals
I was able to get the netbook to see my USB flash drives but it wouldn’t read from them. The help site says that input devices are supported but nothing about storage devices. A wireless mouse worked fine.
A Developer Netbook?
I’ve read some of the press referring to this as a developer netbook. It is if you only consider that developers will generally use equipment that is more early adopter and hasn’t all the warts worked out. It isn’t a developer laptop that you can develop on as your sole machine as John Resig noted. Some shell access would be nice but that interferes with the fact that an update blows away the whole partition. I would love to be able to partition or reserve an area that wouldn’t be wiped at any moment. I have been looking at Cloud9, a web-based IDE to do some coding. That solution would still require a server but it is more elegant that a SSH situation. Perhaps an extension/app that saved to the download directory and synced on reconnect could work. There is already Dropbox JS code out there. My goal for this thing is to be able to create a Chrome extension from start to finish using only the CR-48. The one get out of jail free card I will give myself right now is using an outside service to zip the files(probably will do something on Google App Engine). There is also the developer switch that allows you to enable NaCl or install another OS.
Conclusion
The CR-48 fits a good niche for a conference computer. Being able to come back from sleep instantly and browse over Wifi for 8 hrs is a major plus. Office workers that live mostly in Microsoft Office won’t notice much difference I don’t think. It’s not like they don’t take a coffee break anyways when the network is down. As a developer machine, it’s going to be a stretch. With a suite of apps that use the HTML5 Application Cache, it might just be possible.
Visor and TotalFinder bring awesome to OS X
One of my pain points in my recent forays into OS X has been the lack of a reasonable Quake/Guake terminal and the hand holding OS X puts you through when dealing with files. As a Linux user, even though I used Ubuntu, I lived on the commandline. Whether it was pushing to git or ssh-ing a machine, or starting up Eclipse, many tasks went quicker by going to the commandline to do them.
I’ve been used to hitting a quick key combo and getting a terminal. Terminal.app fails in this capacity. Visor gives you these features along with tabbing. It might seem like a small thing to a non-developer but we devs are extra crotchety about our machine setup when we have it the setup the way we want it. You can check out Visor at http://visor.binaryage.com.
Happy with the new addition to my little plot of OS X, I was minding my own business reading OSNews and came across another creation from BinaryAge, TotalFinder. TotalFinder is an evolution of OS X Finder that adds tabbed folders (much like Google Chrome) and you can unhide-hide files with a dropdown menu. That is much easier that the alternative of running
defaults write com.apple.Finder AppleShowAllFiles YES
and then restarting Finder. Re-hiding them requires the same sort of command. That’s too much to remember if you ask me.
Other key features include:
- dual mode or two finder windows shown side-by-side, clutch for moving files between directories, and
- folders on top mode, seriously Apple why isn’t this standard.
I’ve only been playing around with TotalFinder for about half a day but I’m pretty happy with it. It makes OS X feel more like home to me. Now if only someone could write an app to move my window icons to the right where they should be...
TotalFinder licenses are $15 for a single license or $10 each for a 3-pack, totalling $30. More info at totalfinder.binaryage.com
Customize Google Chrome with Chromizer
One of the things you miss from running an OS where the browser and the OS are one and the same is the ability to actually see the desktop. In Chrome OS running on the CR-48, the new tab that shows all your apps and recently opened websites has become the defacto desktop.
If Google's sparse white background doesn't do it for you, you can apply one of the themes available in the Chrome Web Store or you can make your own. There are several tools on the market to do so but the easiest is Chromizer. It allows you to upload a single image file and it gives you a extension with your theme bundled that you can install or give to others to install. The process was super simple and in 10 minutes, I had already played around with more than a handful of custom themes.
For those of you not on the Chrome netbook, you can create themes as well. You can try it out at http://chromizer.com.
Authoring eBooks Review
Riding the StartupBus to SXSW
This year, I’m heading to SXSW for the first time. What will be unusual about this trip is the way I’ll be getting there. Instead of flying or driving, I’ll be riding in a WIFI coach bus with other techies and geeks from the Bay Area and tasked with creating a startup during the bus ride.
CoffeeScript Gotchas
I've been converting a game that was previously in Java to CoffeeScript andfor the most part it hasn't been that bad. The painful parts have been errors that compile but escape notice until you inspect the generated JavaScript. Take for instance, the following function. It is incorrect but what is wrong with it?
equals = (letter, letter2) ->
if letter is letter2
true
false
console.log equals('a','a')
Although CoffeeScript returns the last value, the above code is incorrect because even if the condition is true, it always returns false. We can fix it by changing the third line to return true. That forces the compiler to properly scope the true and false. We could alternatively make line four else false and it would do the same thing.
Here is a inner function that is declared in a CoffeeScript class. Looks fine and compiles too.
mouseOver = (event) ->
state = game.isSelecting
if state is yes
this.attr {fill: 'red'}
game.tempWord.push @letter
else
this.attr {fill: 'blue'}
The problem occurs when the function is triggered by RaphaelJS. @letter is expanded in JavaScript to this.letter and this has a different when Raphael invokes it. We can account for this by using a local variable self to dereference this. That's not to say that you should always use the self instead of @variable-name but be aware of possible scope issues.
This JavaScript Kata sums it up pretty well.
---
My book "Learning HTML5 Game Programming..." is currently in early access on Safari Books Online, buy it here: http://bit.ly/html5gamebook
Five Cool Things About The HTML5 Canvas
- You can easily clear a Canvas by changing the size.
Or even resetting the size to itself. However, if you'd like clear only a portion of the canvas, you can use context . clearRect(x, y, w, h) or context . fillRect(x, y, w, h). The difference between the two is that clearRect clears to black and fillRect paints over the rectangle with whatever fillStyle you have set. - You can save a image from a canvas.
toDataURL returns an encoded Base64 string representing the image. You can then use that image data in other canvases or image tags. Please note that toDataURL is on the Canvas object NOT the context. There isn't a standard lib to convert directly to a file in the HTML5 spec but generally you would either use a backing server or decode the data from Base64 and write to a file using the FileWriter API. FileWriter isn't well supported atm. - You can do pixel manipulation on canvases.
To retrieve the ImageData from a canvas, you would call getImageData(0,0, imageWidth, imageHeight) on a CanvasContext. What you get back is an object with properties for the width, height of the the image data and RGBA values for every pixel in the ImageData object. After doing the manipulation, you would call putImageData to push the results into a canvas. Here's an example that converts an image to grayscale. - You can create multiple canvases on a page.
One reason to use multiple canvases is if you want to do alot of manipulation to a particular canvas and don't want to worry about having to save and restore the context. You might want to cache the orientation of an object as Seth Ladd did in his this code for his Google IO talk. - You can texture a canvas with video.
As far as the canvas is concerned, a video is just a series of images that are compatible with the canvas. You can display them on canvases as is or do pixel manipulation. Tab Atkins Jr. has a couple of examples on his site here and here.
Note: Tab's demos pre-date the advent of requestAnimationFrame by about a year or so.