Brain Flush

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?

Advertisements

26 Comments »

  1. I’m struggling with the same problems as you regarding Grails and Eclipse. I got really excited to hear that your 2nd method works, but unfortunately it will *not* work on Windows. The “classes” symlink that you create in ~/.grails//projects/ is really a “.lnk” file in Windows, and unfortunately Grails won’t recognize it and create a regular classes directory right next to it. Maybe could be worked around with some more hacking the Clean script, but it’s just getting uglier…

    Anyway thanks for sharing your experience and some tips in this arena.

    Comment by Eric — May 5, 2008 @ 8:59 pm

  2. Hi Eric,

    yes that is unfortunate. I actually hoped this problem wouldn’t even appear on a Windows machine, but apparently it does. I am not aware of a similar solution for Windows right now.

    Unless of course, there would be a way to tell Grails not to compile to your home directory in the first place (on a Windows machine, I guess it will compile to your Documents And Settings folder?), which would make my hack redundant.

    Maybe dissecting Grails’ build.properties file will help to shed some light on this, but right now I am too tired of fighting with Grails’ build process. Maybe the people on the mailing list can help?

    Comment by Matthias — May 5, 2008 @ 9:14 pm

  3. I have not tried what you mention above yet but I have used “junction points” in place of symbolic links on windoze.

    here are a couple of helpful links
    http://technet.microsoft.com/en-us/sysinternals/bb545046.aspx
    http://shell-shocked.org/article.php?id=284
    http://www.rekenwonder.com/linkmagic.htm

    I’ll try it out today and let you know how it goes

    Comment by Josh — May 24, 2008 @ 4:13 pm

    • I am new to groovy – grails and ran into the same problem. How do you run a Groovy project inside of the Eclipse IDE that has the groovy plugin installed?

      Comment by Mitch Hall — April 21, 2011 @ 7:26 pm

  4. Hey guys,

    I just sat down with a friend of mine who tried to compile my app under Windows, and after well over an hour of ripping out more hair, we figured out the solution for Windows (without any additional software required):

    1. Go to your scripts folder in your grails home and find Init.groovy. Change line 58 to e.g. this:
    projectWorkDir = “c:/workspace/${baseName}”

    where C:/workspace is your Eclipse workspace; this only works if your project name for your grails app is identical to the Eclipse project name for that same app.

    Then change line 59 to this:
    classesDirPath = System.getProperty(GrailsApplication.PROJECT_CLASSES_DIR) ?: “$projectWorkDir/web-app/WEB-INF/classes”

    2. Go to your Eclipse project settings and set both Java compiler output and Groovy builder output to web-app/WEB-INF/classes.

    3. Open your .classpath with a text editor and add this line (of course with brackets):
    classpathentry kind="lib" path="web-app/WEB-INF/classes"

    you have to do it this way, because you cannot add an output folder as a class folder via the GUI (will be filtered out).

    Of course editing the Ant.clean target has to be done as well, as outlined in my posting.

    That should do the job and it works for both Windows and Linux.

    Tell me if it works for you as well.

    Comment by Matthias — May 24, 2008 @ 5:29 pm

  5. Haven’t tried this new method, but I did want to report that like Josh I’ve had some success with the “2nd try” method listed above and junction magic (http://www.rekenwonder.com/linkmagic.htm). Been running it for a few weeks now without any snags.

    Comment by Eric — May 26, 2008 @ 10:38 pm

  6. […] 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 […]

    Pingback by Grails + Eclipse Quick Tip #1 « Brain Flush — May 28, 2008 @ 9:07 am

  7. I just walked through these issues this morning trying to get grails working for gorm classes. I still can’t seem to get past the:

    Severity and Description Path Resource Location Creation Time Id
    Invalid duplicate class definition of class Author : The source /Users/wxlund/library/workspace/grails-app/domain/Author.groovy contains at last two defintions of the class Author.
    One of the classes is a explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name.
    @ line 1, column 1. library/grails-app/domain Author.groovy line 1 1215365217511 1287

    I’ve been working passively on the problem for the past few weeks because it works fine in the Grails Console. However, since making the changes this morning I think that’s broken now as well.

    Thanks for the great explanation though. I’ve been trying to find this kind of explanation for awhile. I’m going to try IntelliJ again.

    Comment by Wayne Lund — July 6, 2008 @ 6:37 pm

  8. Hi there,

    Looks promising. I tried to use your suggestions ;)

    I made the following changes to Init.groovy and Clean.groovy to make them more generic and usable across platforms

    Init.groovy (from line 58 down)
    ========
    // fx c:\workspace
    grailsEclipseWorkspaceDirPath = System.getProperty(‘ECLIPSE_GRAILS_WORKSPACE’)
    // typically: web-app/WEB-INF/classes
    grailsEclipseClassesDirPath = System.getProperty(‘ECLIPSE_GRAILS_CLASSES_DIR’)
    eclipseEnabled = System.getProperty(‘Enable_Eclipse_Grails’) == “true”

    // default setting
    projectWorkDirDefault = “${grailsWorkDir}/projects/${baseName}”
    // eclipse specific
    projectWorkDirEclipse = “${grailsEclipseWorkspaceDirPath}/${baseName}”

    // set projectWorkDir depending on if eclipse for grails enabled
    projectWorkDir = eclipseEnabled ? projectWorkDirEclipse : projectWorkDirDefault

    // default setting
    classesDirPathDefault = System.getProperty(GrailsApplication.PROJECT_CLASSES_DIR) ?: “$projectWorkDir/classes”
    // eclipse specific
    classesDirPathEclipse = System.getProperty(GrailsApplication.PROJECT_CLASSES_DIR) ?: “$projectWorkDir/$grailsEclipseClassesDirPath”

    // set classesDirPath depending on if eclipse for grails enabled
    classesDirPath = eclipseEnabled ? classesDirPathEclipse : classesDirPathDefault

    classesDirPathEclipse = System.getProperty(GrailsApplication.PROJECT_CLASSES_DIR) ?: “$projectWorkDir/$grailsEclipseClassesDirPath”

    // set classesDirPath depending on if eclipse for grails enabled
    classesDirPath = eclipseEnabled ? classesDirPathEclipse : classesDirPathDefault

    Creating and running a default Grails app (eclipse_grails_enabled=false)

    C:\workspace\GrailsTest>grails run-app

    Welcome to Grails 1.0.3 – http://grails.org/
    Licensed under Apache Standard License 2.0
    Grails home is set to: C:\Program Files\Groovy\grails-1.0.3\grails

    Base Directory: C:\workspace\GrailsTest
    Note: No plugin scripts found
    Running script C:\Program Files\Groovy\grails-1.0.3\grails\scripts\RunApp.groovy
    Environment set to development
    [mkdir] Created dir: C:\Documents and Settings\zedbkma\.grails\1.0.3\projects\GrailsTest\classes
    [groovyc] Compiling 6 source files to C:\Documents and Settings\zedbkma\.grails\1.0.3\projects\GrailsTest\classes
    [mkdir] Created dir: C:\Documents and Settings\zedbkma\.grails\1.0.3\projects\GrailsTest\resources\grails-app\i18n
    [native2ascii] Converting 11 files from C:\workspace\GrailsTest\grails-app\i18n to C:\Documents and Settings\zedbkma\.grails\1.0.3\projects\GrailsTest\resources\grails-app\i18n
    Error starting Sun’s native2ascii:
    C:\workspace\GrailsTest>

    Why this native2ascii error???

    Clean.groovy
    ==========
    // line 28 down
    Ant.property(environment:”env”)
    grailsHome = Ant.antProject.properties.”env.GRAILS_HOME”
    eclipseGrailsEnabled = Ant.antProject.properties.”env.Enable_Eclipse_Grails”

    // line 45 down
    target ( cleanCompiledSources : “Cleans compiled Java and Groovy sources”) {
    def webInf = “${basedir}/web-app/WEB-INF”
    if (!eclipseEnabled) {
    Ant.delete(dir:”${webInf}/classes”)
    } else {
    Ant.delete(includeEmptyDirs:true) {
    fileset(dir:”${webInf}/classes”, includes:”*/”)
    }
    }

    The clean target works just fine under both scenarios

    And finally:

    Adding the lib entry to .classpath for all grails eclipse projects
    Go to grails\src\grails\templates\ide-support\eclipse\.classpath

    // line 14 down
    @grails.libs@
    @grails.jar@

    Comment by Kristian Mandrup — July 11, 2008 @ 11:32 am

  9. Hi Kristian,

    thanks for sharing this.

    As to the native2ascii error, this seems to happen an aweful lot. It has something to do with the i18n mechanism. If you get this error, just run “grails package” and it should go away.

    Comment by Matthias — July 11, 2008 @ 11:41 am

  10. On Win XP, I followed all the instructions in the “2nd Try” method and used http://www.nedprod.com/programs/Win32/SymLink/
    to create the symbolic link on windoze.

    Worked like a charm.

    Comment by durp00 — August 12, 2008 @ 10:36 pm

  11. The latest version of the plugin (well in SVN anyway) now eliminates the need for bin-groovy altogether. I will release the plugin to the beta site (later on tonight) and I would love to hear if it helps.

    http://dist.codehaus.org/groovy/distributions/updateDev/

    You may need to do some manual configuration of existing groovy/grails projects to remove the java builder (if you disable class file generation). The plugin should do it for you, but you never know right? Please feel free to ping me directly about this too. I am on twitter: http://twitter.com/GroovyEclipse

    Comment by James E. Ervin — September 2, 2008 @ 8:48 pm

  12. That’s great news James, thanks for sharing. I’ll get to it as soon as I can.

    Comment by Matthias — September 3, 2008 @ 9:08 am

  13. I tried “Fixing The Class-File Hell: 2nd Try” with the last http://dist.codehaus.org/groovy/distributions/updateDev/ and still but every time I try to insert a breakpoint in let us say a controller I get:
    “””
    Unable to install breakpoint in due to missing line number attributes. Modify compiler options to generate line numbers attributes.”
    Reason:
    Absent Line Number Information
    “””
    I have checked the debugging info is inside the generated class files. I can see the “LocalVariableTable” inside them.
    I have noticed though for the “$_closure.class” generated files I do have the line numbers in Eclipse Debug perspective (From Thread information there)

    I am trying all this now in Windows XP, using ‘junction’ utility (similar to linux ‘ln’)
    , Eclipse Ganymede.

    Groovy individual scripts can be debugged and run without any problem.

    Any thoughts?

    Best regards,

    -Nestor

    Comment by Nestor Urquiza — September 5, 2008 @ 6:55 pm

  14. It seems like a bug reported as critical on JIRA http://jira.codehaus.org/browse/GROOVY-2208

    So the class files are missing LineNumberTable information and that is why Eclipse won’t be able to provide debugging capability for them.

    I am wondering if any of you guys found this problem so far? BTW this will affect any IDE and not just Eclipse.

    Comment by Nestor Urquiza — September 5, 2008 @ 8:56 pm

  15. I only have problems debugging Groovy code after modifying it in a running session. The debugger is then unable to attach the source code to the compilation. I have to restart the servlet container for it to work again.

    Comment by Matthias — September 15, 2008 @ 10:04 am

  16. To make a grails project integrate with eclipse on windows is simpler.
    set the output location for both java and groovy to:
    web-app/WEB-INF/classes
    This is mentioned in the post.
    change the Clean.groovy to not to delete the classes dir and its contents under web-inf/classes by commenting:
    target ( cleanCompiledSources : “Cleans compiled Java and Groovy sources”) {
    def webInf = “${basedir}/web-app/WEB-INF”
    /*Ant.delete(dir:”${webInf}/classes”)*/
    Ant.delete(file:webXmlFile.absolutePath, failonerror:false)
    Ant.delete(dir:”${webInf}/lib”)
    /*Ant.delete(dir:classesDirPath)*/
    Ant.delete(dir:resourcesDirPath)
    Ant.delete(dir:testDirPath)
    }

    note commenting this makes life easier because every time you deploy a war you don’t have to build the project again to repopulate classes dir.

    Thanks
    Sachin

    Comment by Sachin Mittal — October 4, 2008 @ 9:21 am

  17. Great fix thank you … I have followed it through (2nd try method) and got rid of the original error.

    Unfortunately when running grails in Eclipse I now get an error relating presumably to the fact that the /classes directory already exists and was not expected (since i have commented out the delete. I am running OS X Leopard.

    Error is
    “Compilation error: Directory /Users/laurajtownsend/.grails/1.0.3/projects/testgrails/classes creation was not successful for an unknown reason
    : Directory /Users/laurajtownsend/.grails/1.0.3/projects/testgrails/classes creation was not successful for an unknown reason
    at org.apache.tools.ant.taskdefs.Mkdir.execute(Mkdir.java:64)….”

    Has anyone seen this or can help me fix (comment out?) the part that wants to make the classes directory again?

    Thanks

    Laura

    Comment by Laura — October 30, 2008 @ 4:58 pm

  18. HI

    Regarding the Build Error: “Failed to compile configuration file” … Config.groovy … “No signature of method: groovy.util.ConfigSlurper.parse()”

    I was able to fix by adding the JDK tools.jar to the project classpath:
    – Project Properties > Java Build Path
    – On Libraries tab, click Add External JARs, then select ‘..\jdkx.x.x\lib\tools.jar

    This is recommended in the instructions on how to setup the Eclipse IDE pluggin.
    See: http://grails.org/Eclipse+IDE+Integration

    I am now using Grails 1.0.4.

    Comment by Paul at Work — November 29, 2008 @ 1:41 pm

  19. It worked! … sort of. I was able to import a project and everything worked except the Acegi plugin, which refused to compile. I even imported the jar libraries that were inside of it and it still couldn’t find the classes for things like GrailsUser. Etc.

    I feel like it’s sssosooooo close. But alas, I just can’t use Eclipse with Grails. So, back to doing it with Vim, like it’s the 1980’s all over again.

    Comment by Barnaby — December 8, 2008 @ 8:58 pm

  20. Remote debugging seems to work. I have enabled the “Disable Groovy Compiler Generation Class Files” checkbox. Start the app with “grails-debug run-app” instead of “grails run-app”. Then use remote debugging on eclipse by creating a run-config for “External Java Application”, select the correct project and port (normally 5005, check for the text “Listening for transport dt_socket at address: 5005” in the grails windows) and connect your eclipse to the server.

    Comment by marcmit — February 24, 2009 @ 1:08 am

  21. Very useful information, thanks!

    Comment by David — July 19, 2009 @ 2:45 pm

  22. […] Grails applications in Eclipse using the Groovy-Eclipse-Plugin was everything but enjoyable for me. Matthias Käppler summed it up best when he wrote: Grails and Eclipse: Not So […]

    Pingback by SpringSource: A Groovier Eclipse experience « creatified.com — August 12, 2009 @ 7:11 pm

  23. Ok, I don’t know if this topic is still interesting for you but I found something helpful in the Eclipse mailinglist: http://dev.eclipse.org/newslists/news.eclipse.tools.jdt/msg14410.html. I’m just trying it you, I admit, can’t promise it works…

    Comment by Graphity — April 15, 2010 @ 12:44 pm

  24. […] See the original for Detail   […]

    Pingback by Grails and Eclipse: Not So Groovy - Grails with Eclipse — September 22, 2010 @ 12:26 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: