Thursday, July 2, 2009

FogBugzReporter: NetBeans + Ivy = IvyBeans

(This is my second post in a series about FogBugzReporter, a small open source app that I originally wrote in Java and later ported to Groovy.  See the first post for more information and for links to other posts in the series as I write them.)

When I first ported FogBugzReporter to Groovy, I was able to take advantage of a free 1 year license for JetBrains IntelliJ IDEA (version 7) and its nice Groovy support.  I had good experiences with it, but when the year ran out, I was both reluctant to pay for a new license and curious to explore the Groovy and Grails support in NetBeans.  At the same time, I was interested in trying out Apache Ivy for dependency management.  As it turns out, Laurent ForĂȘt wrote a plug-in for NetBeans called IvyBeans which integrates Ivy with the NetBeans internal build infrastructure.  So, if you reference a library in your ivy.xml, not only is it downloaded into your local repository (located in %USERPROFILE%/.netbeans/<netbeans_version>/modules/ext/cache on Windows) but it's also added as a NetBeans project dependency.  This post describes what it was like to move to NetBeans and start using Ivy.

Although I'd previously used NetBeans 6.1 and 6.5 for some small Grails apps, by the time I got around to moving FogBugzReporter into NetBeans, the 6.7 release process had already reached Milestone 2 or 3 (it has since been released!).  Since the Groovy/Grails plug-in for 6.7 provided better, more up-to-date support, I decided to jump directly to it.  After installing the base version and adding the Groovy/Grails plug-in, I looked over the options for opening the project in NetBeans.  I couldn't see any easy way to either import the project based on the existing IntelliJ files or create a new project pointing to the existing sources (any suggestions?), so I ended up doing something weird along the lines of creating a new project and checking out the files from Subversion on top of it.  I don't remember the exact steps, but even if I did I might not repeat them here, since I'm sure there's a better way to do it.  Once that was done, I was a bit disappointed to discover that I was unable to designate my Groovy script (MainFrame.groovy) as the project's main class.  This was even true after I converted the script into a class and gave it a main method.  Fortunately, it's still possible to run the app inside NetBeans by selecting that file and choosing Run File (Shift+F6) from the Run menu.

Next, it was time to try out Ivy and IvyBeans.  At the time, there was no up-to-date build available, so I built from HEAD, but at this point you can just download 1.1 Milestone 3.  Installation is as simple as extracting the zip you just downloaded and then following the basic plug-in install steps.  I searched on MVNRepository.com to find the appropriate org (a.k.a. group) and name for each of the two libraries my project uses.  I then removed the libraries from the NetBeans project, temporarily making the IDE unhappy.  After I added lines of the following form to ivy.xml and then executed a Clean and Build on the project, Ivy downloaded the libraries, IvyBeans made them available to the project, and the build completed successfully.  Pretty cool!

<dependency org="com.something" name="library_name" rev="1.2.3" conf="compile->*" />

My transition to NetBeans isn't totally finished, but it's almost there.  One thing I still need to figure out is what changes are needed to allow me to run an external build using the ant build.xml file generated by NetBeans – I think it involves specifying a few properties that are currently absent when ant is run standalone.

As I've said in most of my posts, please tell if you know of a better way to do any of what I've described above.  I'm definitely not an expert in NetBeans or Ivy.

Saturday, June 27, 2009

Embedded Groovy as an Application Extension Language

I recently worked with my client to add an extension mechanism (in this case, a very simple plug-in system) to their intranet Java web application.  It's initially meant for use by professional services staff and possibly other advanced users in the future.  Our first thought was to go with JavaScript via the Java Scripting API, since that pair of technologies was already in use elsewhere in the system for simple filtering expressions (e.g., "value > 10 && value < 100").  I wrote a few examples and discovered that the code quickly became a weird hybrid of Java and JavaScript that was very hard to read. ("Is that a Java String or a JavaScript String?…")  After a brief conversation with my client, we decided to instead go with Groovy for several reasons.  We can keep the code around as Strings for now, but easily compile it to class files later if our needs change.  Groovy's integration with Java is excellent and easy to understand.  If the user knows Java, but isn't comfortable with Groovy's many cool features, he or she can write normal Java (except for inner classes) and have it interpreted/compiled as Groovy.  What follows is a description of how I set it up.  Please let me know what you think of this approach, especially if you can suggest a way to improve it.

Each extension is a Groovy class extending a Java abstract adapter class that provides default implementations of all but one of the methods in a Java interface (ScriptingInterface).  The Java code used to load the extension gets a GroovyClassLoader using the following code:

GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader());

I use the following code to get the relevant class and instantiate it via its no-arg constructor, catching the (entertainingly-named) MultipleCompilationErrorsException along with several other exceptions:

String code = "<Groovy>"; 
Class<? extends ScriptingInterface> clazz = loader.parseClass(code); 
ScriptingInterface script = clazz.newInstance();

Does that sound like a reasonable way to do it?  It definitely works, but I'm not sure it's the best way.

Update: Ack!  For some reason, my Blogger settings changed from "New Posts Have Comments" to "New Posts Do Not Have Comments" through no action of my own!  While I try to figure out how to fix it (now that this post is no longer new), you can add any comments to this post's listing on DZone.

Update2: Problem fixed.  It turned out to be possible to turn on comments for a single post via the Blogger post editor.

Tuesday, June 16, 2009

Boston Grails Users' Group!

Last night, I watched an interview with Dave Klein done by Scott Davis of ThirstyHead at JavaOne 2009, in which they discussed Dave's upcoming book, Grails: A Quick-Start Guide. At the end of the interview, Dave mentioned that one of his kids had put together a site called g2groups.net, which helps people find and start Groovy/Grails user groups. I visited the site and was very excited to see that Boston has a newly formed group and that their first meeting is on Thursday! I have a conflict, but this is important enough that I plan to drop my original commitment to attend. See you there!

Wednesday, May 27, 2009

FogBugzReporter: Introduction

This is the first post in what I plan to be a series about a small application named FogBugzReporter that I began writing in October of 2007.  I'd recently started using the on demand edition of FogBugz from Fog Creek Software to track my time spent consulting and was disappointed to discover that it had no direct way for me to generate time reports.  Fortunately, I discovered that along with the web UI, FogBugz also had a pseudo-REST API for interacting with the application (I say "pseudo-REST" because almost all operations can be performed with HTTP GETs, including ones that change state on the server).  I read the API docs, quickly wrote a simple Swing application in Java, and made it available to the rest of the FogBugz community.  Soon after, I started experimenting with Groovy and realized that porting the app would be a nice way to get some experience with the language, including SwingBuilder and the great APIs for processing XML.  I did that and eventually moved the code from a private Subversion repository to one on Google Code under an Apache license.  Until a few days ago, it sat for the most part unchanged.  In the meantime, my Groovy skills have improved a bit (I'm still no expert), the language has evolved, and the technologies around it have grown.  In this series, I plan to gradually bring the application up-to-date and polish up the code.  I'll update this posting with links to the other posts in the series as I write them.

Posts:

Planned Posts:

  • FogBugzReporter and Griffon
  • Suggestions?