Twitter GitHub Facebook Instagram dirv.me

Daniel Irvine on building software

Java, Vim and Buildr--oh my

9 September 2014

Having always been a supporter of self-flagellation, I felt it was about time I wrote some Java.

Joking aside, it’s 9 years since I last worked with Java. In that time I’ve become a Vimmite and abhor the idea of going back to an IDE. So just how easy is it to write Java code in Vim? I’ll be exploring that in my next few posts.

The obvious first step was to create a new Java project, complete with tests and the ability to run those tests through Vim with standard key mappings.

Maven is the quintessential build system for Java. I installed it on my Mac via Homebrew (brew install maven, of course). Creating a simple project is done with a command like the following.

mvn archetype:generate -DgroupId=com.mycompany.app \
                       -DartifactId=my-app \
                       -DarchetypeArtifactId=maven-archetype-quickstart \
                       -DinteractiveMode=false

With this command, Maven creates a simple source file in src/main and a corresponding JUnit test file in src/test. Excellent. It also creates a pom.xml file which is the main build file. All good, except...

From my Ruby experience I’ve seen and believed the wonders of Rake, the much loved build system which is simple and yet powerful in exactly the right amounts. Seeing Maven’s pom.xml file, combined with a cursory glance at the Maven documentation, left me with a fear that this was an archaic system that wasn’t worth learning. I found myself asking: surely there’s a better way? And indeed there is.

Enter Buildr

Buildr is essentially Rake with added Java tasks and support for the “standard” Maven project structure. Maven’s pom.xml is replaced with a standard Rakefile (now called buildfile) using the Rake DSL. From perusing the Interwebs I’ve gained a sense that Maven has fallen out of favor recently because of its hulking vastness. The slim-and-sleek Buildr would appear to be the new hotness.

Converting a Maven project to Buildr

  1. Open a terminal or command prompt window.
  2. Install Builder: gem install buildr did it for me. You’ll need to have Ruby installed for this to work; more complete instructions are available on the Buildr installation page.
  3. Change to the directory of your existing Maven project, where the pom.xml file resides.
  4. buildr --generate. This creates a buildfile based on the pom.xml. It’ll look something like the below.
    # Generated by Buildr 1.4.20, change to your liking
    # Standard maven2 repository
    repositories.remote << 'http://repo1.maven.org/maven2'
    
    desc '[jTtt]'
    define 'jTtt' do
      project.group = '[com.danielirvine.jttt]'
      project.version = '[1.0-SNAPSHOT]'
      package :jar, :id => 'jTtt'
    end
     
  5. Delete pom.xml, if you dare.

Your project can now be compiled with buildr, and tests can be run with buildr test.

Disclaimer: This worked for me on the simplest of Maven project files. If you’ve got any custom tasks then this is unlikely to go so smoothly for you.

Running tests via Vim

My standard Vim practice is to use -f to run tests in one specific file, and -R to run all tests. I created ~/.vim/ftplugin/java.vim with the following content:

function! GetJavaTestName()
  let objName = expand('%:t:r')

  if match(objName, Test) == -1
    let objName = objName . Test
  endif

  return objName

endfunction

map <buffer> <leader>R <CR>:call VimuxRunCommand(clear; buildr test)<CR>
map <buffer> <leader>f <CR>:call VimuxRunCommand(clear; buildr test: . GetJavaTestName())<CR>

Running tests gives output like this:

(in /Users/Daniel/Work/jTtt, development)
Testing jTtt
Running tests in jTtt
Trying to override old definition of datatype junit
    [junit] Testsuite: com.danielirvine.jttt.AppTest
    [junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0.045 sec
    [junit] 
    [junit] Testcase: testApp took 0.005 sec
    [junit]     FAILED
    [junit] null
    [junit] junit.framework.AssertionFailedError
    [junit]     at com.danielirvine.jttt.AppTest.testApp(AppTest.java:35)
    [junit] 
    [junit] Test com.danielirvine.jttt.AppTest FAILED
The following tests failed:
com.danielirvine.jttt.AppTest
Buildr aborted!
RuntimeError : Tests failed!

(See full trace by running task with --trace)

...which fits nicely inside a Tmux pane.

Stay tuned for more exciting Vim and Java adventures!

About the author

Daniel Irvine is a software craftsman at 8th Light, based in London. These days he prefers to code in Clojure and Ruby, despite having been a C++ and C# developer for the majority of his career.

For a longer bio please see danielirvine.com. To contact Daniel, send a tweet to @d_ir or use the comments section below.

Twitter GitHub Facebook Instagram dirv.me