Brain Flush

May 28, 2008

Grails + Eclipse Quick Tip #1

Filed under: Software Development & Programming — Tags: , — Matthias @ 9:07 am

More Automated Builds

here is a little hint on how to make building your Grails apps from within Eclipse a little less explicit. The goal is to avoid being asked to manually issue a “grails package” after each re-build. Plus, if you followed my hints on how to let Grails and Eclipse compile to the same directory structure, you won’t need to issue “grails clean” anymore. Simply running Project –> Clean… and then running the Grails launcher will suffice for successful compilation and deployment if you follow these instructions.

  1. Go to you project properties and select the Builders entry. You should see two builders: Groovy builder and Java builder.
  2. If you haven’t yet configured an external tools launcher for a “grails package”, click New…, otherwise import that builder
  3. If you have to create the builder, set the following fields:
    • set Location to the folder where the Grails executables reside on your system
    • set Working Directory to ${workspace_loc:/your_project_name}
    • set Arguments to “package”
    • In the Build Options tab, check the fields After a “Clean” and During manual builds
  4. move the new builder to the bottom

I would also advice to create a keyboard shortcut to issue a manual build. For myself, I reassigned Ctrl+B to “Build project” instead of “Build all”.

When you now “Clean” your project and run the “run-app” launcher (I assume you have one!), Eclipse will first build your project and package it for deployment. The packaging is conditional though: if the sources are up-to-date, the new builder will be excluded when launching the app.

Advertisements

May 3, 2008

Grails and Eclipse: Not So Groovy

Filed under: Software Development & Programming — Tags: , , , — Matthias @ 7:16 pm

Grails is a Web application framework for rapid prototyping based on the Groovy scripting language, a Java dialect that compiles to Java byte code. Grails strongest advantage over similar frameworks (e.g. AppFuse, to name a more popular one) is its consequent use of the Convention Over Configuration paradigm, making it almost a no-brainer to set up a full featured Web app using Grails. Grails also relies heavily on the dynamic nature of Groovy to provide useful utility functionality or inject commonly used features such as logging objects and CRUD accessors for domain objects at runtime.

While Grails is an excellent piece of software, it is completely beyond me why apparently almost zero effort has been undergone to make it work flawlessly with one of the most (if not THE) widely used IDEs out there: the Eclipse IDE.

From day one, I had nothing but trouble running Grails applications in Eclipse. There is a document over at grails.org which has instructions for Grails + Eclipse, but it is erroneous and contradictory. While I still suggest to read that document, I will offer solutions to most of the problems you will probably still encounter, even after following that guide.

All instructions below worked for Grails 1.0.2 and Eclipse 3.3 on Ubuntu Linux 8.04.

The Groovy Eclipse Plugin

I assume that the Eclipse Groovy plugin has been installed.

By default, the output directory setting for Groovy compilations is left empty. That means your Groovy files in Eclipse will be compiled to your Grails project root. That is bad, as it confuses Grails. Set it to a different folder, e.g. bin-groovy. In any case, regardless what the Eclipse guide over at grails.org says, leave the “Disable Groovy Compiler Generating Class Files” box unchecked, but check “Disable Check Package Matches Source Directory”. Two reasons: If you check the first one, you won’t be able to debug your Groovy sources, but of course you want that. If you leave the second unchecked, you will get errors related to Groovy’s Spring DSL config in resources.groovy. This error is safe to ignore however.

Make sure to follow the instructions for debugging Groovy applications in Eclipse, too.

Fixing The Class-File Hell: 1st Try

Grails will generate an Eclipse .project file for you after issueing ‘grails create-app’. However, there are several issues with that file. First of all, Grails always compiles your Groovy and Java sources to the directory ~/.grails/<ver>/projects/<proj>/classes, but the generated project file sets the default output folder for Java class files to web-app/WEB-INF/classes. Furthermore, the Groovy plugin may compile to yet another directory, say bin-groovy. In other words, by default an imported Grails app is doomed to make you trouble, because the ‘grails’ command will always compile to a different folder than Eclipse does, and you will end up in a class-file mess where Eclipse will not recognize any changes made by Grails and vice versa.

The solution obviously is to make both Grails, the Eclipse Java compiler and the Groovy Eclipse plugin all compile to the same output directory. However, this is not as easy as it sounds. The best solution would be to tell Grails to compile to a different directory, but I haven’t found a way to do so.

The next best solution would be to create two symbolic links in your project root: bin and bin-groovy, both pointing to the Grails output directory (see above, it’s in your home directory under .grails/) and then tell the Eclipse Java compiler to compile to bin/ (via Project -> Properties -> Java Build Path -> Default Output Folder) and the Groovy plugin to compile to bin-groovy (via Project -> Properties -> Groovy Project Properties -> Groovy compiler output location).

While this solves the class-file hell, it leads to a weird problem: At least for me, I wasn’t able to run my Grails app from its Eclipse launcher anymore without the launch failing with a cryptic error message:

Failed to compile configuration file <proj_path>/grails-app/conf/Config.groovy: No signature of method: groovy.util.ConfigSlurper.parse() is applicable for argument types: (Config)

As of now, no one on the grails-user mailing list was able to say what is causing this, but of course it’s a show stopper, because you won’t be able to debug your application anymore (please note that this only affects Eclipse, your app would still start from the command line using ‘grails run-app’).

The third solution is somewhat ugly, but it works.

Fixing The Class-File Hell: 2nd Try

This approach is as follows: Instead of symlinking from bin and bin-groovy to the Grails output folder, we do it vice versa:

  1. leave the Java output folder to its default value: web-app/WEB-INF/classes
  2. the Groovy class files must also go there, so set a bin-groovy symlink to the same directory
  3. add bin-groovy to the build path: Project -> Properties -> Java Build Path -> Libraries -> Add Class Folder
  4. go to ~/.grails/<ver>/projects/<proj>, remove the classes/ folder and create a symlink “classes” to the full path of the web-app/WEB-INF/classes directory (e.g. ~/workspace/<proj>/web-app/WEB-INF/classes)

What we have done now is to turn around the sym-linkage: Grails will now compile to web-app/WEB-INF/classes. You may ask: What is the difference to the first approach?! Actually, there shouldn’t be any difference, but now you will notice that the ConfigSlurper error is gone, and you can run your app again from within Eclipse. THAT is why we do it (in lack of a better explanation…).

Unfortunately we’re still not 100% done. The reason is: As soon as you issue a ‘grails clean’, the symlink will become invalid and any “creational” follow-up commands like ‘grails compile’ will fail. The problem here is that ‘grails clean’ does not merely empty the ‘classes’ directory, but removes it alltogether. So we need to tell Grails not to remove the directory upon clean, but only its contents. A little background: Whenever you issue a command like this, you are effectively executing a Gant script (that’s the Groovy DSL for Apache Ant). These scripts reside in your Grails installation directory, in the scripts/ subfolder. Find the Clean.groovy script and perform the following changes:

  1. Find the target cleanCompiledSources
  2. Change the first call to Ant.delete to this code:
    Ant.delete(includeEmptyDirs:true) {
       fileset(dir:"${webInf}/classes", includes:"**/*")
    }
  3. Remove/comment the line Ant.delete(dir:classesDirPath)

save the file and exit. When you now run ‘grails clean’, only the content of classes/ will be removed, not the directory itself.

And that’s it!

Grails and Eclipse should now love each other. Ain’t that a happy ending?

Blog at WordPress.com.