Live geek or die tryin'

Use Java 7 for IntelliJ’s SBT Plugin

IntelliJ IDEA runs on JRE 6, and so does its SBT plugin.

If you need to use a more recent version of Java (and you should):

  • Open the Preferences panel
  • Go to the SBT section
  • Tick the Use alternative JRE option
  • Click the arrow on the right of the field to check if the IDE suggests the desired JRE
    • If so, choose it.
    • Otherwise, look for the path by yourself.
      It’s /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home on my Mac.

WebSockets: INVALID_STATE_ERR: DOM Exception 11

This error can be caused by many reasons, among them what happened to me: I tried sending a message via the WebSocket before the connection was completely opened.

What you should not do:

ws = new WebSocket("ws://localhost/ws");
ws.send('foo');

What you should do instead:

ws = new WebSocket("ws://localhost/ws");
ws.onopen = function () {
  ws.send('foo');
}

Java: No Main Manifest Attribute

I won’t go though explaining how to create a build.xml file, the official manual, which is really good, does it better than I would.

The error in question occurs because the java executable, after reading the Manifest file from the inside of the JAR, doesn’t know what is the entry point of the program; i.e. the class that contains the ugly public static void main(String[] args) method.

To fix the error, that class’ full name needs to be specified in the build.xml file.
For example:

<jar destfile="${jar}" basedir="${build}">
    <manifest>
      <attribute name="Main-Class" value="my.awesome.package.Main" />
    </manifest>
</jar>

Building a Search System With MongoDB (and Scala)

If you need a search system for your web application, you can either roll your own, or use a system that does it for you, such as elasticsearch.
I’ve recently had to choose, and the second option was an overkill since I was looking for something simple.

The main idea here is using an index collection, let’s call it searchresults, that will be updated each time the real entities change, thanks to hooks implemented on the default create/update/delete tasks.
searchresults will be the only collection to get queried, thus making requests simple and search results’ retrieval fast.

More in details

I’ll use two entities in my example: User and Song.

The SearchResult model has 3 fields:

  • entityType: a discriminator field that contains the indexed entity type, user or song in this case.
  • entityId: You think my name is Captain Obvious, don’t you?
  • keywords: An array of keywords related to that search.

That class’ signature should look like this:

case class SearchResult(
  id:         ObjectID,
  entityType: String,
  entityId:   ObjectID,
  keywords:   List[String]
)

Paired with the class described above, a Searchable trait will help forcing the implementation of some methods and properties, and more importantly be used as a type in methods signatures.

trait Searchable {
  def entityType:    String = this.getClass.getSimpleName,
  getSearchKeywords: List[String],
  entityId:          ObjectID
}

Now, each of your entities class, User and Song, will implement the Searchable trait, define the entityType property and implement the getSearchKeywords() method. The entityId property, or some entity with the same name, should already be implemented by your MongoDB driver.

Example of a getSearchKeywords() method:

def getSearchKeywords: List[String] =
  List(this.username, this.firstname, this.lastname).filter(_.nonEmpty)

The next step is to implement the hooks that update the index collection each time users and songs are updated too.

If you use Casbah and Salat for instance, the entities are created and updated when calling the save() method, and deleted when remove() is called.
These methods should be overriden, the hooks behaviors added to them —creating or updating the concerned SearchResult entry, in case of save() for example—, yet without altering their initial role.

override def save(user: User) {
  createSearchResult(user, SearchResult.findByEntity(user))
  super.save(user)
}

private def createSearchResult(user: User, searchResult: Option[SearchResult]) {
  searchResult match {
    case Some(sr) => SearchResult.save(sr.copy(keywords = user.getSearchKeywords))
    case None => SearchResult.save(SearchResult(
      entityType = user.entityType,
      entityId   = user.id,
      keywords   = user.getSearchKeywords
    ))
  }
}

The last thing to do, is creating a MongoDB index on the keywords field of the searchresults collection.
This can be done in one single command:

mongo myAwesomeDB --eval "db.searchresults.ensureIndex({keywords: 1});"

We’re done. I guess.

Review Your Code With Git

Whether you want to commit a part of your changes only or simply check your work before you commit it, one of the Git commands you probably use the most, add, can help you doing it throught its option -p (patch).

This option allows to choose the changes you want to stage.
Or word for word, from Git’s man:

Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the index.

This is how it works, or rather how I use it:

After executing git add -p ., git enters an interactive mode, from where many actions can be taken. Below are the ones I use the most.

  • If the diff is too long, you can try splitting it with s. That will split it into the smallest possible parts.
  • If you want to stage the diff, simply choose yes.
  • Otherwise, say no.
  • When the whole diff has been viewed, the interactive mode will quit automatically. You can do it yourself tough, through the classic ^C, or by selecting q.
    Note that this will simply quit the interactive mode and won’t undo your actions.

Feel free to ask ? about the other commands meaning, they might be useful in some cases.

git add -p your best friend to review your code and not to commit stuff like console.log().
Make the most of it!