Friday, January 22, 2010

Sharing IntelliJ IDEA Project Files in Version Control

There are quite a few benefits to having IDE project files properly stored under version control:

  • most people want to use an IDE and will need to configure the project somehow
  • a shared environment reduces costs within a corporate workplace
  • a VCed project means that the project file branches with your codebase. Need to work on an old branch? No problem, the project file already exists.
  • casual contributors will have an easier time making patches for your project
  • an IDE can provide checkstyle and coding standards to your code
And when the files are stored improperly in version control, you create a nice changelist headache for yourself and turn away the casual contributor.

Here are three simple rules on how to properly share an IntelliJ IDEA project file in version control:

Rule #1 - Check-in the .ipr and .iml files
Rule #2 - Set an ignore flag for the .iws file (your workspace file). All proper VCSs allow you to do this.
Rule #3 - Make IDEA Project Variables for all the variables that vary (it's kinda the definition of variable, you know). Some common variables you'll probably need are "Tomcat Home", "Groovy Home", and "JDK Version".

Creating variables is really easy. Open the .ipr/.iml in a text editor and scan for hardcoded paths or values. When you find one just replace it with $variable_name$. Now when IDEA starts, it prompts you for those variables if they are not defined. These are IDEA variable stored in your HOME directory; they have nothing to do with your operating system environment variables. Here's what a prompt looks like:

See that red dialog? Clicking it opens a screen where you can add values to the variables:


Adding a value should be pretty self-explanatory.

The Gotchas - There are a few gotcha's to be aware of...

Using multiple versions of IDEA is not well supported. Most new versions, even minor releases, try to write some extra info to the project files. Not a problem in the corporate world, but more so in the OS one. You might try checking in a backup copy when the project lead upgrade.

Making the JDK Name variable can be somewhat confusing, as it is not a path on your disk. IDEA keeps track globally (for all projects) of your installed JDKs, and each one is given a name. It is easy to find the place in the .ipr where this is specified, but it is not easy to explain to users what their's should be set to. It needs to be the name of an entry from your SDKs in Settings:

Also, changing the inspection profiles can modify the project. The inspections are the codestyle to the project, so it may make sense to have them baked into the .ipr. However, this is an optional place to put them. An inspection profile can be shared or not. If it is shared then it is written to the .ipr, otherwise it is an external file. The Settings screen should be self-explanatory once you understand the Shared checkbox.


Lastly, adding words to the spell checker will add the word to the .ipr file, with a key of your username. I opened a bug for this, as I feel a user's name should never go in the project file, but the JetBrains guys feel that this is OK considering that switching to the ".idea" alternate project layout will separate the files out and avoid the issue. For now, I guess the best advice is to spell words correctly and, if you're not a committer, live with the fact that your project file may be checked out because of this issue.

Is all this worth it? I recently opened the GPars project files, defined an SDK and a Groovy 1.6.7 library, and ran the tests successfully. For me, it was great.

Rule #4 - Profit!

Monday, January 11, 2010

Accelerated GWT Report Card

Student Name:Accelerated GWT
School:Apress
School Year:2008
Teacher:Hamlet D'Arcy
Overall Grade:A-Strong on client side, i18n, and advanced topics.
Grading Scale: A=Outstanding, B=Good, C=Average, D=Poor, F=Fail
 
Teacher Comments
This was a good book and a worthwhile read. It was very strong on the client side and documented many edge cases of the GWT framework without reducing itself to an overly specific "recipe" book.
 
Client Side ProgrammingA-
Knowledge of Standard GWT Widget SetA-
Great coverage of basic widget set. Contains examples and advice about how to layout widgets in various containers, including composing widgets in the Composite class. Sometimes the widget API was explained too completely and it felt like reading Javadoc, but these sections can easily be skimmed. Also, this book was written for GWT 1.4, so UiBuilder is not covered at all.
Knowledge of CSS StylingA
Great coverage of how to work with the CSS of widgets including several good examples. Best coverage of the topic I could find.
General Client ConcernsA
Overall, the client sections are excellent. Serializing your own classes is covered, the output of the GWT compiler is given fair due, and generators for creating custom JavaScript code at compile time are covered. So far, this is the best book on client side GWT that I've found, even though it doesn't cover the 2.0 features.
Knowledge of JSNI (JavaScript Native Interface)D
JavaScript Native Interface is barely covered. In comparison, GWT in Practice covers it maybe too much. Embedding JavaScript in multiline Java comments is the most controversial part of GWT, but it's not the most important. Still, a little more info would be helpful.
 
Server Side ProgrammingB
Knowledge of GWT RPC (Remote Procedure Calls)B
GWT RPC is covered in 14 pages. Do you need more than that? Maybe not, it's pretty straight forward. The appendix does cover some of the newer 2.0/1.5 features, like generics.
Knowledge of InternationalizationA+
Over 30 pages on i18n, including an example using localization at either compile time or run time. Very good chapter.
Knowledge of Security ConcernsB+
Same origin policy and cross site scripting: check. Not as lengthy coverage as in other books, but adequate.
Knowledge of GWT TestingB
GWT Testing is surely the easiest chapter of the book to write. GWT ships with GWTTestCase for testing asynchronous calls and a benchmarking tool for measuring performance, and they are clearly explained all over the Internet. Speed Tracer, the 2.0 profiler that runs in Chrome, is of course not covered.
Creative Code SamplesB
Decent enough code samples (with an occasional error) covering browser history and server sessions, as well as the other topics mentioned. Some of the code samples were a little long and ImageBundle was given too much space given that it is deprecated in 2.0.
Knowledge of Alternative Server StacksD
Nothing on the server side beyond GWT RPC is covered.
 
GWT Best PracticesB+
Tools to Write GWT ClientsA
The Enterprise means constraints: existing domain objects, maybe a crummy DAO, etc. Enterprise GWT apps will need things like custom serializers and custom generators to work around their legacy constraints, and Accelerated GWT covers these topics well.
How to Design GWT ServicesB
General advice about domain objects and writing RPC services is given and a DTO approach is avoided, which pleases me. Overall, however, not a lot of information is given on building "Enterprise" backends, which is part of the book's title.

Sunday, January 10, 2010

60 Second Agility: ROTI Meetings

Always in search of the absolute minimum of ceremony, my last team "discovered" a useful agile practice that takes 60 seconds from start to end: the ROTI Meeting.

After every meeting, on the way out the door, draw a diagonal line on the whiteboard with the labels 0, 2, and 4.
Each person in turn gives a number on how the meeting performed as a "Return on Time Invested" and the person with the marker draws in the rating. Here is the rating scale we used:

0 = "I'd have been better off making a Starbuck's run. Complete waste of time"
1 = "You really should have let me stay at my desk and code"
2 = "This was an OK meeting. About as valuable as if I'd been coding"
3 = "Surprisingly, this was more valuable than if I'd been writing code"
4 = "Wow, this meeting saved me tons of time. Thank goodness I didn't skip it to code"

And then each person answers the same question, "What could be done to improve your number by one point?"

To do this in 60 seconds means there is no discussion. The feedback is what it is; no debating, no fixing problems, and no hurt feelings.

ROTI meetings create tacit, organization knowledge that can be acted upon by team members in the future. It drives a team towards less meetings (almost always a good thing), pushes team members to be more respectful of each others time and expertise, and influences meeting organizers to craft more succinct, on topic, and meaningful gatherings. It takes only 60 seconds so you might as well try it a few time!

... and now the historical details.

ROTI analysis is nicely described in Esther Derby's great book "Agile Retrospectives". The practice in the context of iteration retrospectives takes more lie 5 to 10 minutes. Our team found ROTI to be so effective in retrospectives that we shortened it and held one at the end of every meeting.

The actual ROTI scale is a bit more formal than what we created:

0 - Lost Principle: No Benefit Received for Time Invested Break-Even:
1 -
2- Received Benefit Equal to Time Invested High Return on Investment
3 -
4 - Received Benefit Greater than Time Invested

Lastly, ROTI charts are covered in detail a few other places as well.

For a mere 60 second investment, this practice is worth trying on your team.

Saturday, January 9, 2010

"GWT In Practice" Report Card


Student Name:GWT In Practice
School:Manning
School Year:2008
Teacher:Hamlet D'Arcy
Overall Grade:B (solid effort; time well spent; not enough on client side)

Grading Scale: A=Outstanding, B=Good, C=Average, D=Poor, F=Fail











Server Side ProgrammingA
Knowledge of GWT RPC (Remote Procedure Calls)A+
How Ajax calls are made from the client to the server using GWT RPC is clearly explained in a variety of use cases (almost too many!). The difficult to understand relationship between service interfaces, server/servlet implementations, and the client asynchronous interface is explained in words, with diagrams, and within the IDE. Explaining GWT RPC is where GWT in Practice really shines... and this topic is still relevant today in GWT 2.0.
Knowledge of Alternative Server StacksA
GWT in Practice demonstrates how to consume REST and POX services with GWT, how to integrate Flash for SOAP services (not a good idea IMO), how to use Java Applets(!) for a SOAP client, and how to use Comet for streaming data to clients. The book focuses so much on server side technologies that perhaps it should have been called "GWT Server Stack Recipes".
Knowledge of Security ConcernsA
The Manning "In Practice" imprint means the author is targeting real world developer concerns rather than giving a generic overview, and security is one of these real world concerns. GWT in Practice does a great job explaining all the cross site scripting concerns (and how to work around them), security certificate issues (and how to work with them), and how to configure Tomcat security (which isn't even unique to GWT). It's clear the authors have real experience with securing a GWT app in a variety of contexts.
Knowledge of GWT TestingB
GWT ships with both GWTTestCase (for easing the testing of asynchronous and multithreaded components) and a performance benchmarking tool. The tools are straightforward and covered in every other GWT text as well. While a testing section is essential to any GWT book, this one didn't stand out against the other material. I'd have liked to see more testing best practices. Plus, GWT ships with a new performance testing tool, so this section is starting to age.
Creative Code SamplesB
The book deomonstrates how to turn on history to support the browser back button and how to record and playback certain Comet messages. The former is useful (and part of the GWT project) while the latter seems unlikely to be needed by almost any other GWT developer (and is custom implemented for the book).










Client Side ProgrammingC+
Knowledge of Standard GWT Widget SetC
Granted, the "in Practice" title is not meant to be a basic introduction, but there is almost no material on the standard GWT widget set. If you want to know all the user interface widgets supported by GWT then look elsewhere. However, some widget layout and CompositeWidget material was covered, the GWT in Practice salvages a C grade.
Knowledge of JSNI (JavaScript Native Interface)B
Surely the most controversial part of GWT is the ability to embed JavaScript within multiline comments of Java files. Sounds nasty even if IDEA does support refactoring and highlighting, right? (And as of 2.0, Eclipse does as well). This books contains a ton of JSNI. Pages of it, actually; which isn't always a good thing for the book or for GWT. GWT in Practice will definitely show you how to wrap JavaScript libraries, even if it makes for poor reading. The best part of the JSNI examples was the recipe for adding drag and drop, which appeared twice in the book for some reason. If you need drag and drop or to wrap a JavaScript library then this is the book for you!
Knowledge of CSS StylingB
CSS styling gets a whole 2 pages. Which means there isn't much to say beyond what the browser offers already.
General Client ConcernsC
There simply wasn't enough information about client side programming in GWT in Practice. The example that were shown left me wondering, "Is that something I'll really need to do?"








GWT Best PracticesB+
How to Design GWT ServicesA
This is the only book I found that included best practices about how to design services, which the author recommended using DTOs and keeping interfaces seperate from implementations to decouple physical services. However, some of the diagrams seemed forced and pointless (and they were, did you know Manning requires a visual aid on every spread?)
How to Design GWT ClientsF
What should client side design be in an Ajax application that consists of pretty much just one web page? This wasn't covered at all. Note to authors: please include this in your GWT 2.0 update! Also, there was no coverage of how to deal with degenerate browsers like IE6. This is the bane of my current project and any hints would be appreciated.
Knowledge of the Best Tools for the JobB+
GWT in Practice shows NetBeans, Eclipse, and IDEA in action. The most helpful diagram of how a GWT project is structured was actually an IDE screenshot. For builds, the Maven plugin is covered ad naseum, which is understandable considering the authors wrote it. But still, Maven is dead to me so it was time wasted (now where is that Gradle GWT plugin)?



Teacher Comments
Even in light of the GWT 2.0 release, GWT in Practice holds up as a solid GWT book for newcomers. It definitely favors the server side and gives the client side short shrift. My biggest complaint was that it seemed to be a lot of recipes bundled into an "in Practice" format, and many of the recipes I didn't need (Flex? Applets?). Given the book is from 2008 when GWT had just been released, I wanted to dislike it. But it's held up quite well. It should not be the only GWT book you read, but probably it should be one of them.

Thursday, January 7, 2010

Groovy AST Transformations by Example: Adding Methods to Classes

What can you do with a Groovy AST Transformation? A difficult question, considering the answer is "almost anything". One frequent use of AST Transformations is to write Groovy changes into the JVM .class files so that standard Java tools will know about them. For instance, the bytecode changes produced by @Delegate are visible and usable from plain old Java classes. This example is going to walk you through how to add synthesized methods to a class at compile time using a Groovy AST Transformation and the AST Builder. It makes an interesting test case since it explores some of the edge cases and common pitfalls. This should be fun...

(And for those of you who want to skip all this and just see the code, check out the latest Groovy example in SVN and just run the Ant script).

svn co http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/examples/astbuilder
To start, let's better define our example. Consider the class with a public API and also a standard main() method. Frequently, the main() method simply instantiates the class and calls a single method. Wouldn't it be nice to annotate a method so that it is treated like a main method? What if this were possible:
class MainExample {

@Main
public void greet() {
println "Hello from the greet() method!"
}
}
At compile time, this annotation would synthesize a proper main method and run the same code as greet(). (We'll worry about calling an instance method from a static method later). Transforming this annotation in the AST means that both Java and Groovy would see the main() method. Let's do it; there are three things you need:
  1. An @Main marker interface
  2. An ASTTransformation implementation make the AST changes
  3. A test harness (trust me, you want this)
The @Main marker interface is the easiest piece. The marker interface is used to a standard Java 5 annotation to an ASTTransformation implementation:
@Retention (RetentionPolicy.SOURCE)
@Target ([ElementType.METHOD])
@GroovyASTTransformationClass (["MainTransformation"])
public @interface Main { }
This is just a standard Java 5 annotation. The retention policy is SOURCE so that other objects don't see the annotation at runtime when using reflection (there is no need). The ElementType is METHOD because we only want to apply the annotation to methods. And the GroovyASTTransformationClass is "MainTransformation". This value is the fully qualified classname of the ASTTransformation implementation that the Groovy compiler is going to call when an @Main annotation is found. In practice, you will need to specify a package... I left one off here for simplicity.

So this annotation will wire @Main into a class called MainTransformation. I suppose we'd better go make this class then...

The ASTTransformation interface defines one method:
void visit(ASTNode[], SourceUnit)
The best way to understand the contents of the two parameters is to write several tests and inspect them in a debugger, and then use the AST Browser to analyze the syntax tree. In general, the ASTNode array contains what you want to manipulate and the SourceUnit provides services like error and warning reporting. Here is the skeleton of our MainTransformation that is going to add a synthesized main() method to the class:
@GroovyASTTransformation(phase = CompilePhase.INSTRUCTION_SELECTION)
public class MainTransformation implements ASTTransformation {

void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {

if (!astNodes) return
if (!astNodes[0]) return
if (!astNodes[1]) return
if (!(astNodes[0] instanceof AnnotationNode)) return
if (astNodes[0].classNode?.name != Main.class.getName()) return
if (!(astNodes[1] instanceof MethodNode)) return

MethodNode annotatedMethod = astNodes[1]
ClassNode declaringClass = astNodes[1].declaringClass

// makeMainMethod synthesizes a method!
MethodNode mainMethod = makeMainMethod(annotatedMethod)
declaringClass.addMethod(mainMethod)
}
...
Again, there are a few interesting things to notice here...
  • The compiler phase chosen was INSTRUCTION_SELECTION, which was a completely arbitrary decision. Please, if you want to know which phase to target then ask on the groovy-user mailing list (and asking will give us better hints as to what we need to document on the wiki).
  • The body of the transformations contains many guard clauses as a safeguard against NullPointerExceptions and unexpected input. The AST of classes changes from version to version. Defensive programming and thorough test cases highly recommended.
  • The MethodNode that was annotated comes through in the ASTNode array, and from there you can navigate most anywhere within the syntax tree.
  • The makeMainMethod is going to copy the body of the annotated method and then we will add that method back onto the declaring class.
The last thing to do is define the makeMainMethod that actually creates the main():
MethodNode makeMainMethod(MethodNode source) {
def ast = new AstBuilder().buildFromSpec {
method('main', ACC_PUBLIC | ACC_STATIC, Void.TYPE) {
parameters {
parameter 'args': String[].class
}
exceptions {}
block { }
}
}
MethodNode newMainMethod = ast[0]
newMainMethod.code = source.code
newMainMethod
}
Again, a few bits and pieces to make special note of:
  • The AstBuilder.buildFromSpec is a DSL convenience over the concrete constructors of ASTNode and its subclasses. Thus, the API of buildFromSpec mirrors the API of the ASTNode classes. If you want to understand the arguments and parameters types, then look at the ASTNode Javadoc. In this regard, the buildFromSpec is more about making the code easier to read rather than easier to write.
  • The return type of the method is Void.TYPE and not Void.class. Void.class is a real class with real usages, Void.TYPE is the symbol for "little vee void".
  • The modifiers are ACC_PUBLIC | ACC_STATIC. Notice the use of | and not &. Let me editorialize briefly: I don't understood bitmasks, I never understood them, and people who design APIs around parameters typed as "int modifers" will be first against the wall when the revolution comes. If null was the billion dollar mistake then bitmasks at least deserve to be in the tens of millions range. Anyway...
  • The codeblock of the new main method is just a reference to the codeblock of the method annotated with @Main. This will cause duplicate bytecode to be written out into the .class file (bad) but does make for a small, clear example (good). In production, you probably want to invoke the @Main method instead of copy the body.
Now, as you can see from the javap output, the compiled MainExample.groovy contains a real, live Java main class:
hdarcy:$ groovyc MainExample.groovy
hdarcy:$ javap MainExample
Compiled from "MainExample.groovy"
public class MainExample extends java.lang.Object implements groovy.lang.GroovyObject{
...
public void greet();
...
public static void main(java.lang.String[]);
...
}
Phew! That was a lot of information. The last thing to add is a simple test case using Groovy's TranformTestHelper class. A debugger helps AST Transformation development immensely, and this integration test is one way to hook one up to your transformation. I tested this in IDEA but it should work fine in Eclipse/Netbeans as well:
class MainIntegrationTest extends GroovyTestCase {

public void testInvokeUnitTest() {

def file = new File('./MainExample.groovy')
assert file.exists()

def invoker = new TranformTestHelper(new MainTransformation(), CompilePhase.CANONICALIZATION)

def clazz = invoker.parse(file)
def tester = clazz.newInstance()
tester.main(null) // main method added with AST transform
}
}
This test case takes the example class as a simple File and then compiles it using the MainTransformation we defined. This is a great way to invoke both local and global transformations from unit tests. I'm sure there is an easier way to invoke the static main method without instantiating the class, but I'm tired and don't care all that much. It's just an example!

And that's it... we created a marker interface to trigger an annotation, created an ASTTransformation to add a method onto a class, and wrote a test harness. There are just two loose ends to tie up:

How can a static main method invoke a non static method like Greet? We'll, it can't really. For this example we just copied the method body into the main method. In practice, you'd want to make sure only static methods were annotated.

How are inner classes handled? Short answer: not the same way. You have a test case, so just write a test method and find out!

All the code was checked into the Groovy examples folder along with an Ant script. There's no better time to get the source:
svn co http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/examples/astbuilder
cd examples/astbuilder and away you go.