Announcement Announcement Module
Collapse
No announcement yet.
Baking STS Gradle support into generated Eclipse files Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Baking STS Gradle support into generated Eclipse files

    In my current setup, we use Gradle to generate our Eclipse files (.project, .classpath, etc) and we encourage the use of STS.

    Obviously we would like to take advantage of the STS Gradle Integration plugin for running build tasks within the IDE. We can currently do this, but only if each team member manually configures each of our Eclipse projects to be a Gradle Project (via right-click > Configure... > Convert to Gradle Project). I would rather modify our Gradle scripts to generate the Eclipse files with the "Gradle Project" nature baked in.

    I experimented with this by adding a nature of com.springsource.sts.gradle.core.nature to the .project file and adding a container classpathentry of com.springsource.sts.gradle.classpathcontainer to the .classpath file via the following Gradle script code (1.0-milestone-3):
    Code:
    eclipseProject {
    	natures "com.springsource.sts.gradle.core.nature"
    }
    
    eclipseClasspath {
    	containers "com.springsource.sts.gradle.classpathcontainer"
    }
    The script worked, but the Gradle Project functionality was not complete. The green G icon was not added to the projects and STS could not auto-discover classes on the classpath when editing Java source files. Specifically, the "Organize Imports" (Ctrl+Shift+O) functionality stopped working for those projects.

    Since everything worked when adding the project nature via STS UI, I figure there's something I'm missing. What other changes to Eclipse project files/contents are required for the Gradle Integration to work? What specific changes are made when the Gradle Project nature is added via the UI?

  • #2
    The icon isn't showing because Eclipse overlays icons for nature over each other and when there's more than one, I think it is the first one in the list that takes priority. This shouldn't matter for functionality, only for appearance.

    I think your changes are (or should be) sufficient. These are currently the only changes performed when converting a gradle project (though I'm working on some WTP specific patchups right now).

    Not sure what you are missing, but it could be more something in the IDE state in memory rather than the project XML files. One possibility could be that the contents of the classpath container which is dynamically computed doesn't get refreshed automatically if you just add it with a generator. (My code to conver the projects explicitly triggers a refresh). So you might still need to trigger a 'Refresh Dependencies' (or 'Refresh All') on the projects you are experiencing problems with.

    If you can share with me a sample project + build script I could have a look and see what might be the problem.

    Also, if you are finding that the way the tools work isn't letting you do something you feel like you ought to be able to, then it may be worth thinking about why that is. Maybe there's something wrong with the way the tools work for your particular workflow. If we understand why maybe we can somehow fix the tools. So consider raising a Jira issue with a detailed description of what you'd like to do, and why it doesn't work.

    For example, have you considered using the import wizard to configure/import a whole set of projects/subprojects at once? If it doesn't do what you want, why not? And how would things need to be changed so they work better for you?
    Last edited by Kris De Volder; Aug 31st, 2011, 07:36 PM.

    Comment


    • #3
      Well I feel dumb. I tried it again tonight and couldn't reproduce the issue, so it looks like I had everything I needed.

      I did find that the Import functionality provided by the Gradle Integration plugin doesn't work so well for flat project structures, or at least for mine anyway.

      We use a flat project structure where the root of our multi-project build is a directory/project (containing settings.gradle) at the same level as all of the "subprojects". This was setup before we even started using Gradle, and although it's arguably less intuitive, it works quite well within the Eclipse paradigm. And, fortunately for us, Gradle supports flat multi-project builds out of the box.

      Anyway, I created a new/clean workspace of our existing codebase and attemped to import our Gradle projects into STS using Gradle Integration. I pointed the wizard to the root build project (at same level as all others) and it was able to successfully build/discover the model of all subprojects. However, when I attempt to import any of the projects, I get an "Invalid project description" error saying that the project overlaps itself (see image), regardless of the "Import options" selected. This happens no matter which projects I attempt to import.

      Attachment

      The spring-integration project structure mentioned in the tutorial is obviously not flat, so I can't really compare with my setup. (I did notice that the instructions in readme.txt say to use "./gradlew eclipse" to setup the projects instead of importing via Gradle Integration.) It would be nice if the tutorial referenced an alternative project using a flat structure for people like me.

      It also occurs to me that perhaps STS Gradle Integration is trying to do too much. For instance, out of the 3 main areas of functionality it provides, we already do 2 of them, just not through the IDE. The main benefit I hope to derive from the plugin is the ability to easily see and execute Gradle tasks for particular Eclipse projects, much like the Ant plugin/view works. For the other 2 areas (Import Gradle projects into STS/Eclipse and Manage STS/Eclipse project dependencies from Gradle scripts), I realize it would be ideal to do everything through the IDE, but I think there's benefit in sticking with the lowest common denominator (in this case Gradle) instead of relying on a particular IDE plugin to get the job done. That way, the process doesn't change depending on which version of Eclipse you're using or which plugins you have installed. And for cases like mine, where the work of setting up the build system to generate Eclipse files has already been done, the import functionality simply needs to call a Gradle task for each imported project. Perhaps when the project model is built, Gradle Integration should see that an "eclipse" task already exists and should use it instead. Just throwing that out there.

      One more thing I'd like to mention is that a lot of fine-tuning of our Gradle scripts was done to get the Eclipse classpaths just right for each individual project. For instance, we have Java projects with provided dependencies, and those provided libraries should not be exported as part of the project classpath, nor should they be included in the WTP deployment assembly for the project - both of which are manually-coded customizations. Also, Gradle defines "provided" dependency scopes for web/war projects, but since Eclipse (AFAIK) does not allow classpath references to be scoped, a customization is needed to exclude those dependencies (which may be necessary for compilation) from WTP deployments. Idiosyncrasies like this may be easier to handle in a few lines of Gradle/Groovy code rather than in IDE configuration. In other words, a one-size-fits-all model rarely works well for defining classpaths and build systems, which is why Gradle is becoming more popular.

      Regardless, I appreciate you taking the time to look into this with me.
      Attached Files

      Comment


      • #4
        Originally posted by andrew.goode View Post
        Well I feel dumb. I tried it again tonight and couldn't reproduce the issue, so it looks like I had everything I needed.

        I did find that the Import functionality provided by the Gradle Integration plugin doesn't work so well for flat project structures, or at least for mine anyway.

        We use a flat project structure where the root of our multi-project build is a directory/project (containing settings.gradle) at the same level as all of the "subprojects". This was setup before we even started using Gradle, and although it's arguably less intuitive, it works quite well within the Eclipse paradigm. And, fortunately for us, Gradle supports flat multi-project builds out of the box.

        Anyway, I created a new/clean workspace of our existing codebase and attemped to import our Gradle projects into STS using Gradle Integration. I pointed the wizard to the root build project (at same level as all others) and it was able to successfully build/discover the model of all subprojects. However, when I attempt to import any of the projects, I get an "Invalid project description" error saying that the project overlaps itself (see image), regardless of the "Import options" selected. This happens no matter which projects I attempt to import.
        I'm not sure of this, but it sounds like the project you are trying to import has a file system location inside the workspace. This may be the cause
        of the conflict. The wizard assumes it needs to set up a linked project but can't create one in the workspace because there is something in the
        workspace, in the file system, already there.

        So maybe you are hitting this bug:
        https://issuetracker.springsource.com/browse/STS-2058

        If so, please try putting your project in any location *outside* your workspace folder. Then import them from there.

        The spring-integration project structure mentioned in the tutorial is obviously not flat, so I can't really compare with my setup. (I did notice that the instructions in readme.txt say to use "./gradlew eclipse" to setup the projects instead of importing via Gradle Integration.) It would be nice if the tutorial referenced an alternative project using a flat structure for people like me.
        Sure... nobody has given me an example of a 'flat' project. You have one that you can share? I'd like to play around with it to see if it works, and if not, think of ways to make it work.

        It also occurs to me that perhaps STS Gradle Integration is trying to do too much. For instance, out of the 3 main areas of functionality it provides, we already do 2 of them, just not through the IDE. The main benefit I hope to derive from the plugin is the ability to easily see and execute Gradle tasks for particular Eclipse projects, much like the Ant plugin/view works.
        Does the 'Run As >> Gradle Build" menu not do what you want?

        For the other 2 areas (Import Gradle projects into STS/Eclipse and Manage STS/Eclipse project dependencies from Gradle scripts), I realize it would be ideal to do everything through the IDE, but I think there's benefit in sticking with the lowest common denominator (in this case Gradle) instead of relying on a particular IDE plugin to get the job done. That way, the process doesn't change depending on which version of Eclipse you're using or which plugins you have installed. And for cases like mine, where the work of setting up the build system to generate Eclipse files has already been done, the import functionality simply needs to call a Gradle task for each imported project. Perhaps when the project model is built, Gradle Integration should see that an "eclipse" task already exists and should use it instead. Just throwing that out there.
        I hear you. However, for some people, the classpath container to manage the dependencies is what they really want as the 'first and only important thing'.

        And the import wizard provides more needed functionality for non-flat projects because the existing Eclipse wizard makes it hard to get at sub-projects (it simply doesn't look for sub-projects inside something it deems to be a project).

        But I agree with you in the sense that maybe there should be ways to not use the Gradle classpath container if you don't want to, and just use the generated eclipse files. I'll put some though into it. (You can turn of dependency management on a project, but then you will have to manually run the eclipse task and refresh your project, which probably isn't a very convenient/useful replacement).

        One more thing I'd like to mention is that a lot of fine-tuning of our Gradle scripts was done to get the Eclipse classpaths just right for each individual project. For instance, we have Java projects with provided dependencies, and those provided libraries should not be exported as part of the project classpath, nor should they be included in the WTP deployment assembly for the project - both of which are manually-coded customizations. Also, Gradle defines "provided" dependency scopes for web/war projects, but since Eclipse (AFAIK) does not allow classpath references to be scoped, a customization is needed to exclude those dependencies (which may be necessary for compilation) from WTP deployments. Idiosyncrasies like this may be easier to handle in a few lines of Gradle/Groovy code rather than in IDE configuration. In other words, a one-size-fits-all model rarely works well for defining classpaths and build systems, which is why Gradle is becoming more popular.
        I've also noticed the WTP deployment issues. See some discussions in https://issuetracker.springsource.com/browse/STS-2063

        Incidentally, these issues also exist in the eclipse plugin that generates .classpath.
        The reason why you have to tweak the classpath may be because the eclipse plugin for Gradle didn't do a good job.

        Also, if your build script tweaked the Eclipse classpath 'just right' then we should hope you would get the exact same classpath
        also inside the classpath container. If that's not the case we ought figure a way to make it so (which may require asking for
        extensions on the tooling API).

        Comment


        • #5
          FYI: I've raise this issue: https://issuetracker.springsource.com/browse/STS-2085

          The idea would be to provide an 'import option' that configure only the bare minimum (essentially adding gradle nature only) and relies on the user's build script 'cleanEclipse' and 'eclipse' tasks and their generated files for anything else.

          That puts the onus completely on the user to get the configs just right, but I gather that is what some users may want.

          Comment

          Working...
          X