Sunday, July 22, 2012

Simple Guice integration for Dropwizard

If you haven't come across it yet, Dropwizard is a nifty new framework designed to streamline and simplify development of lean web services which are inherently "ops-friendly". By "ops-friendly", I mean that it provides out of the box support for and gentle encouragement to use things like health checks and metrics monitoring. By "lean", I mean that these services are run from within their own JVM processes, with embedded Jetty as a server. This idea of multiple, self-contained, fail-fast processes is best described by the Twelve Factor App.

So with Dropwizard, you extend from the base Service class, and add things to the Environment on startup (e.g. Jersey Resources, Providers, etc). I've created a simple extension to the Service class which does some classpath scanning to automatically install your resources, providers, health checks and tasks for you, via Guice, allowing you to use Dependency Injection throughout your application for object dependencies. Check it out on github! (IMHO) It's quite simple to integrate into your project, and I've found it to be very useful so far, in that I can simply create a new resource class with a @Path annotation, create a constructor marked with @javax.inject.Inject, and it will automatically be wired up and installed into the REST container.

Let me know what you think! If I get enough interest (read: any) then I'll throw up the binaries on an accessible maven repo.

Update (26 Sep): I did end up getting interest, and have since made this available on the central maven repo.

Friday, July 20, 2012

ProTip: Debugging Minified JavaScript using Chrome DevTools

Here's yet another reason why I develop exclusively in Chrome: they've got a killer feature in the JavaScript DevTools which will format any script file, even if it's been minified, and allow you to place breakpoints on that formatted output!

If you're working on troubleshooting an issue in a production app, for example, you'll have something like this:


If you notice, there's a button on the bottom toolbar that looks like a pair of curly braces { }. If you click that:


Then voila! Pretty-printed!


And I can set breakpoints and troubleshoot!


Saturday, July 14, 2012

Building CanJS with Maven (or Ant)

CanJS and other similar JavaScript frameworks are great for creating modular applications and keeping source files small and cohesive, but we all (should) know that when it comes to web site performance, it's important to keep the total number of downloads to a minimum. This becomes especially important when you start to factor in mobile devices, where the cost per connection is much higher than on desktop browsers.

Luckily, CanJS (and most of the others, I might add) includes the ability through StealJS of compressing and concatenating all of the source files for your application into a single production.js, as well as doing the same for your CSS files, into a single minified production.css.  When you use the generators which come with DoneJS / JavascriptMVC to create a new app, you'll notice in the folder structure a scripts folder, which contains a build.js and build.html. Steal uses Rhino to load the build HTML file, which includes a single call to load the main steal.js core and bootstrap your app (e.g. ../steal/steal.js?yourapp). It then tracks all of the imports, JS, CSS, and EJS, and bundles them into either the production.js or the production.css. Note: the folks over at Bitovi been busily cooking up a new "packages" feature which I haven't yet had the chance to play around with, which promises to shrink the size of the monolithic production.js into more on-demand modules.



The generated scripts folder of a DoneJS app. Also note that there are a few other fun features in that folder besides building, which I can go over in greater detail in a future post.

Building with Maven (err, Ant)

So now back to the subject of this article: how does one integrate this cool build feature into their existing build system? I've got it working in a Maven build (albeit via an Ant task), since the server-side component of my application is Java.
   
    org.apache.maven.plugins
    maven-antrun-plugin
    1.7
    
     
      org.apache.ant
      ant-nodeps
      1.8.1
     
       
    
     
      build-donejs
      prepare-package
      
       
        
        
        
         
         
        
        
         
         
        
        
         
         
        
        
        
                  
              
              
        
         
          
          
          
         
         
          
         
        
        
        
        
            
                
            
        
       
       UTF-8
      
      
       run
      
     
    
   

Things to note in this setup:

  • I've split my web application into multiple distinct DoneJS apps; the line is drawn at the point where there's a distinct HTML page (in this case, login, app, and admin are separate pages).
  • I'm hosting my static content out of /src/main/resources/assets, which is sort of a convention when writing DropWizard applications (more on that awesome framework in a future post!)
  • I'm attaching this execution to the prepare-package build phase, since it takes a while (on the order of 5 minutes or more) and it's important to fail fast on the unit test phase. I've already moved all of the relevant resources into target during process-resources.
  • The production build can fail for a number of reasons, including syntax errors in your JS files, so it's important to look for the production.js files in your output directory and fail the build when they are missing. If you don't, there's a chance you will deploy a broken build to production and your users will not be terribly thrilled!

Not quite done yet!

There are two more steps to do in order to fully take advantage of this awesome build stuff.

First, you need to reference the production.css stylesheet in your html files. Do so like this (in your document's head, of course):

This will give you 404's while in development mode, and your app will flicker a bit in that mode since you're using StealJS to import your CSS files, but in production mode the production.css file will be present and everything will be blazingly fast.

Next, you need to tell StealJS to load your production.js file. I've done so in my Ant task by using regexreplace to replace the references to steal.js with steal.production.js.


  


So there you have it. Add this plugin definition to the build / plugins section of your pom, and run mvn clean package to generate the production files!

Wednesday, July 11, 2012

Who's var is it, anyway?


Consider the following snippet of JavaScript code:
var cells = document.getElementsByTagName('td');

for(var i=0; i<cells.length; i++){
  var cell = cells[i];
  cell.addEventListener('click', function(){
    cell.style.backgroundColor = '#00F'; // which 'cell' ?
  }, false);
}
Does the click listener function do what it’s supposed to? Why or why not?

Closures and Scoping and Vars – Oh, my!

If you’ve gotten this far, it’s probably safe to say you’re aware of the fundamentals of the var keyword. It’s also likely that its use has been hammered into your consciousness as a “best practice” coding habit, and that’s a Good Thing™ (polluting the globe and the global namespace are equally heinous).

So, you follow this advice faithfully, and always declare your variables before you use them:
function foo(arg) {
  var a = 0;

  if( arg ) {
    var b = ‘arg: ‘ + arg;
    console.log( b );
  }
}

Here’s the caveat: unlike other C-style languages, JavaScript variables are NOT block-scoped; they are only global- or function-scoped. Those curly braces provide no protection for your poor vars.

What does this mean? I can update the previous code like this:
function foo(arg) {
  var a = 0;

  if( arg ) {
    var b = ‘arg: ‘ + arg;
    console.log( b );
  }

  console.log( ‘still b: ‘ + b );
}

One more thing…

In JavaScript, variables can be declared after they are first used. How is this possible, you (hopefully) ask? Because of a funny thing that the language parser does, called var hoisting.
foo = ‘bar’;
var foo;

// is implicitly understood as:

var foo;
foo = ‘bar’;
Because of this, it’s a good idea to declare variables at the top of functions. In our original example, the language understands it like this:
var i, cell;
var cells = document.getElementsByTagName('td');

for(i=0; i<cells.length; i++){
  cell = cells[i];
  cell.addEventListener('click', function(){
    cell.style.backgroundColor = '#00F';
  }, false);
}
Note that because the compiler moved the var to the top of the scope (and we don’t have block-scoping in JavaScript), our click handlers are all closing on the same cell instance, which will have the value of the last table cell element at the end of the for loop, so our click handlers will all only effect the last table cell in the document!


Reference: https://developer.mozilla.org/en/JavaScript/Reference/Statements/var

Monday, July 9, 2012

Simple(r) String Templates with Commons Lang

Whenever I have a need to use string templating in a project, I reflexively turn to Velocity, which works great, but it:
  • is "heavy": can be difficult to get into a project and functional, has some quirks with classloaders and logger systems, etc
  • is old: last updates were back in 2010
Velocity is also loaded with features like control constructs, loops, branches, etc, which seem like overkill when all I really need to do is format email notifications with some variables (I've already gone the route of client-side view templates for my UI stuff these days).

I know there are a million ways to solve this using homegrown regex's and other such things, but I found a convenient helper in Commons Lang3: StrSubstitutor. It allows you to replace variables in a string, denoted by:
${varName}
I've written a simple wrapper around it, which can pull a template string from a file on the classpath, caching it using a simple WeakHashMap.  This could be extended to use the nicer caching framework found in the fantastic Google Guava project, perhaps.

An example use of this class might be to stick a template text file into src/main/resources/templates/foo.template (for all of you fellow Maven'rs out there!), and invoke it like:
String output = Templates.template("templates/foo.template")
                         .value("foo", "bar")
                         .value("other", "val")
                         .render();