2012-02-23

firebase

Firebase from Scratch, pt III: A Maven Interlude

In a series of posts we’ll do “Firebase From Scratch”, an introduction to Firebase and its concepts and ideas. Hopefully, reading this series will give you a firm grasp of what Firebase is and what it can do.

Actually, I lied in the last section: We won’t talk about the server game implementation here. Instead we’ll take a quick peak at Maven and how Firebase uses it. If you plan to roll your own using Ant or other tools, this is probably good for you to know anyway.

Maven? What Maven?
Really, if you’re developing in Java you already know this stuff. But if you’re new to the language, this is something you need to read up on, especially as a large part of the Java ecosystem is build with Maven. So if you need it, start here: What is Maven?

Here we will focus on only three of Maven’s aspects, as they are used in Firebase development.

  • Packaging: There’s Firebase specific types for each build, which will make sure you get artifacts out from each build that can be deployed right into a Firebase installation.
  • Developing: You can actually run Firebase right from the command line. This makes it extremely fast to test your games.
  • Quick setup: Firebase comes with so-called Maven archetypes, making setting up new projects a breeze.

So, we’ll ignore dependency management for now, although we will get back to it later in the series when we get down to class loading and best practises.

Archetypes: The Quick Start
In Maven speak, an “archetype” is a skeleton project and a way to quickly create a new project. A template if you will. So, you can let Maven itself create a new project, complete with POM file, folder structure and even example code. All the major Firebase artifacts – games, services and tournaments, have Maven archetypes already, and here’s an example:

mvn archetype:generate
      -DarchetypeGroupId=com.cubeia.tools
      -DarchetypeArtifactId=firebase-game-archetype
      -DarchetypeVersion=1.8.0
      -DarchetypeRepository=http://m2.cubeia.com/nexus/content/groups/public

As you probably understand, the above should be on one line, so remove all line breaks before you try it.

Have a good look, in the middle you’ll find that “archetypeArtifactId” is set to “firebase-game-archetype”. Now what do you think would happen if you replaced “game” with “service”, or “tournament” on that line? That’s correct, you’d create a service or tournament project instead. Neat huh?

Configuring a POM file
But if you already have an existing project, with an existing POM file there’s some basic information you need to add in order to use Firebase specific features. All this information is added automatically if you use the archetypes above, and you can skip this section. But if you want to understand, or roll your own, here’s what you need in your POM file:

<build>
 <plugins>
   <plugin>
     <groupId>com.cubeia.tools</groupId>
     <artifactId>archive-plugin</artifactId>
     <version>1.8.0</version>
     <extensions>true</extensions>
   </plugin>
 </plugins>
</build>

<repositories>
 <repository>
   <releases>
     <enabled>true</enabled>
   </releases>
   <snapshots>
     <enabled>true</enabled>
   </snapshots>
   <id>cubeia-nexus</id>
   <name>Cubeia Repo</name>
   <url>http://m2.cubeia.com/nexus/content/groups/public</url>
 </repository>
</repositories>

<pluginRepositories>
 <pluginRepository>
   <releases>
     <enabled>true</enabled>
   </releases>
   <snapshots>
     <enabled>true</enabled>
   </snapshots>
   <id>cubeia-nexus</id>
   <name>Cubeia Repo</name>
   <url>http://m2.cubeia.com/nexus/content/groups/public</url>
 </pluginRepository>
</pluginRepositories>

That was an awful amount of XML wasn’t it?  But it is really simple: first it tells Maven that there’s a plugin involved in the build process and specifies what it is called and what version to use. Then it sets up two repositories where Maven can go when it wants to find dependencies, such as the build plugin you just specified.

Is that all? Well, in reality you will almost always depend on the Firebase API as well, so you will want this:

<dependencies>
 <dependency>
   <groupId>com.cubeia.firebase</groupId>
   <artifactId>firebase-api</artifactId>
   <version>1.7.4-CE</version>
   <scope>provided</scope>
 </dependency>
</dependencies>

Here’s a small thing to note: We’ve set the “scope” of this dependency to “provided”. This is because when you actually run your game (or service or tournament) it will be within Firebase, and the API JAR will already be present on the class path. So you don’t need it packaged and included along together with your artifact, Firebase will “provide” it when it is time to execute.

Packaging
Each Maven project ends up creating artifacts. The most common of which is an ordinary Java JAR file. However, when deploying a game, service or tournament into Firebase you need special packaging. But this is trivial using Maven: If you’ve configured your POM file as described above, all you need to do is to set the “packaging” element to one of the following:

  • “firebase-gar” – For games…
  • “firebase-sar” – For services…
  • “firebase-tar” – For tournaments…

As Maven doesn’t normally know about these packaging types it will look to it’s build plugins, and the Firebase “archive-plugin” you’ve configured will kick in and package the project for you.

So for example, a POM for a game archive might start like so:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>game-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>firebase-gar</packaging>
  <name>my little test game</name>

  [...]

But hang on! What does this “packaging” thing actually do? Simple: It will use Maven to compile your code, using all the knowledge about the project found in the POM file. It will then package the resulting JAR into a Firebase artifact together with all relevant dependencies, in other words all dependencies not in scope “provided” or “test”. So now when you do…

mvn package

… you will get a Firebase artifact, ready to be dropped into a server!

Running Firebase
But wouldn’t it be cool if you could not only package your code, but actually run it immediately? Why, that’d be cool, and it is also entirely possible! When we’re done here you’ll be able to do this…

mvn package firebase:run

… and not only will you get your code packaged up, Maven will download and start a Firebase installation with your code already deployed, ready to be tested. This will save you from copying artifacts across and restarting Firebase just because you want to test something you just wrote.

In order for this to work, all you need to do is to tell Maven that there’s another plugin you want to use in the build. In the build plugin section of your POM, add:

<plugin>
  <groupId>com.cubeia.tools</groupId>
  <artifactId>firebase-maven-plugin</artifactId>
  <version>1.7.4-CE</version>
</plugin>

That’s all! Now when maven encounters your “firebase:run” above, it will search it’s plugin and delegate command. Firebase will be downloaded, configured and started for you! The first time this happens it will take a little longer as Firebase needs to be downloaded, but after this your game should be started in a matter of seconds.

On our Wiki you’ll find all the above information, just slightly compressed: Firebase and Maven