
Gradle STS Support -- 2.7.0 -- Tutorial
Note: The latest version of this file can always be
found here.
This tutorial will take you through the process of using the STS-Gradle
tooling to import a Gradle multi-project into STS and execute some
Gradle tasks on the imported project(s). This tutorial does not cover
how to install the Gradle tooling into STS. We will use spring-integration
project as a running example throughout this tutorial. If you want
to follow along, the first step is to checkout the spring-integration
source code from git.
To checkout the source
code from git on the commandline use the following command (note
the --recursive bit is important for this particular git repository!).
git clone
https://github.com/SpringSource/spring-integration
This will create the "spring-integration" folder directly below
whatever directory you typed the command in.
Importing Existing Gradle Project(s)
Now that we have the source code checked out we can use the Gradle Import Wizard to import a
subset of the spring integration projects into an Eclipse workspace.
This wizard is accessible via the "File
>> Import ..." menu.
The first thing you have to do in the wizard is point it to the root
folder of your Gradle project. Click the "Browse" button and find the
folder, or simply enter the path to your project folder if you remember
it.
A typical Gradle project may consist of a hierarchy of (sub)projects.
Before you can select which (sub)projects you are interested in you
must request the Gradle API to construct a Gradle project/sub-project
structure model. Click the "Build
Model" button to do this.
Warning: This may take some time, so
be patient!
- Building the model may take some time. How much time depends on
the complexity of your project and how many of the build script's
dependencies can already be found in the cache.
- For spring-integration, an initial "Build Model" with a
completely cleared .gradle cache may take a few minutes to complete.
After some time, once the model has been constructed, you will be able
to select which projects you wish to import into the workspace. You
could elect to import everything by clicking the "Select All" Button. However, let's
assume we are only interested in the "spring-integration-mail" project
for now, so we only select this project.

If a project is selected and that project has an inter-project
dependency on another project, then this other project must also be
imported. Otherwise, the imported project would have problems with its
classpath (missing dependencies). The import wizard uses the project
dependency information provided by the Gradle tooling API to check
whether you have properly selected all required projects. In the
screenshot above, a missing dependency on "spring-integration-test" is
detected and reported.
To fix it, select the missing project (but another missing dependency
will be reported) or use the quick and easy "Select required" button which will
automatically select required projects based on your current selection.
In this case, it will select "spring-integration-core" and
"spring-integration-test".
You may or may not want to import the root project (in this case,
containing the main build script). Let's say we want to import the root
project in addition to what we already selected. If you
click the root project, you will see that it automatically
selects/deselects all the subprojects below it. If you don't want this
(and right now we don't) you can uncheck the "Auto-select subprojects" option.
Import options: Besides
selecting which projects to import, the wizard also provides
some additional options to control how the projects will be represented
in the STS workspace.
create resource filters:
enabling this option will add resource filters to the
imported projects to "hide" nested projects from the parent project.
This deserves some further explanation. Eclipse (and
therefore STS) essentially does not support project hierarchies. Only a
"flat" project structure is supported in Eclipse and projects can not
contain other projects.
To overcome this limitation, a Gradle project hierarchy is flattened
into a list of Eclipse projects. The projects will be imported as
"linked projects" so that nesting structure is still maintained in the
file system structure of the imported projects. However, if you import
both a parent and (some of) its children in this way, it will appear as
if the resources (files and folders) in the children are present
multiple times in the workspace: once in the child itself and also once
inside a nested folder of the parent project that contains the child.
Although Eclipse supports this kind of setup, and it is possible to
work with workspaces that show the same underlying file aliassed in
multiple locations in the Eclipse workspace, it can be confusing to us
(the users :-).
For example if you pressed "CTRL-SHIFT-R" to "open resource" and
searched for one of these aliassed resources, you would see that
resource appear multiple times. To avoid this, keep the "create
resource filters" enabled. This will configure the parent project in
such a way that the children's project's resources are treated as
"invisible/non-existent" in the parent.
use hierarchical project names: choose
between two different project naming schemes.
names of the imported Eclipse project's can be chosen
freely by the user. Since the projects are represented as links to the
actual file system location, the names of the projects don't affect the
underlying project structure. Of course, choosing sensible names will
help in remembering what each Eclipse project represents in terms of
the Gradle project hierarchy!
The wizard will give an initial name to each imported project based on
one of two provided naming schemes. This choice only affects the initial names assigned by
the wizard, you can still rename the projects after importing them.
hierarchical: the name of each project consists
of the name of each ancestor in the path leading to the project and the
project itself, separated by dots. For example the
"spring-integration-test" project would get Eclipse name
"spring-integration.spring-integration-test" in the hierarchical naming
scheme.
non-hierarchical: only
the name of the project itself (not its parents) is used. For example
"spring-integration-test" will be imported as a project called
"spring-integration-test".
It is possible that the non-hierarchical naming scheme leads to name
conflicts (if more than one project in the hierarchy has the same
name). The wizard will detect this situation and signal it as an error.
If you see this error you will need to use the hierarchical scheme
instead. Note that you can still rename the projects after they have
been imported.
create working set
'spring-integration': creates a working set based on the root
project's name and adds all imported projects to this workingset.
If the working set already exists this option will say
"add" instead of "create". It will still add the projects to this
workingset, but, since it already exists, won't try to create it again.
additional working sets:
This provides a similar UI to the standard Eclipse
import wizard for adding projects to working sets. It allows you to add
the imported projects to an arbitrary number of working sets. You can
use this instead of (or in conjunction with) the previous option. The
previous option is more convenient and quick (in terms of numbers of
clicks and keystrokes required) but if you need more control over the
working sets and/or their names, this UI is provided as a more general
fall-back option.
For this tutorial we will choose non-hierachical project names. This
is the best option here since most of the sub-project names already
contain the parent project names to start with. For the other options,
we leave them at their default settings and click the "Finish" button to perform the
actual import. This is shown in the screenshot below

Once you click finish, the selected projects will be imported into the
Eclipse workspace. This operation should go fairly quickly since the
required Gradle model for it was already constructed.
Imported Project Auto-configuration
The import wizard will automatically cofigure imported projects as
follows:
- A Gradle class path container
is added to dynamically compute
the project's binary "jar" dependencies.
- the project's source folders
are configured
- dependencies between projects are configured as Eclipse project dependencies
- A "Gradle Nature" is
added to each project (shown in the UI
as a bold, green "G" overlayed in the bottom right corner of the
project icon).
The sceenshot below shows the workspace right after the import
finished:

A few things are worth noting:
- You will probably notice a background job (bottom right of
the workspace window) called "Update Gradle Classpath Container". The
Gradle classpath container is an Eclipse class path entry representing
all the binary project dependencies (typically these are jar files
downloaded to your Gradle cache folder). This job may take a long time
to complete, especially right after the first import, because it is
downloading all the dependencies into the Gradle cache folder. This
initial update may take several minutes.
- The current implementation of the Gradle tooling API does not
provide good progress information (yet), so if you examine the Job
queue more
closely, you may notice that sometimes it appears as if the job's
progress bar is
stuck. Be patient, it may take several minutes but the Job should
eventually complete. Subsequent updates should be much faster since the
dependencies are already downloaded.
- Eclipse, by default, does not show working sets in the
package explorer. If you want to use workingsets to organize projects
in your workspace, you can enable this from the package explorer's
configuration menu (under the little triangle in the top-left corner of
the package explorer view, change "toplevel elements" from "projects"
into "workingsets").
The screenshot below shows the package explorer view, with "workingsets
as toplevel elements" enabled, after the classpath container update has
completed. The "missing project" errors are now gone. The
screenshot also shows the downloaded .jar entries in the classpath
container (under "Gradle Dependencies").
Refreshing Project Configuration Data
Presently, the Gradle tooling API which we built upon does not tell us
when a Gradle project model needs to be updated. As a result, the
configuration
will become outdated. To force various aspects of the project
configuration to be recomputed you can invoke the commands in the Gradle context menu accessed by right clicking on the Gradle project.

The Gradle context menu provides the following commands:
Disable(or enable)
dependency management: Remove/add the Gradle class path
container from/to the project.
Removing the container means that you intend to take
personal responsibility for managing the project's dependencies and do
not want to have the Gradle tooling do it for you at all.
Refresh Dependencies: for
each of the selected projects (one or more Gradle projects can be
selected. All selected projects must have dependency management enabled)
- Invalidate and request a new Gradle model from the tooling
API
- Recompute the contents of the class path container
- Recompute and reconfigure project dependencies
Refresh Source Folders: Like
Refresh Dependencies, but recomputes and reconfigures the project's
source folders.
Refresh All: combination
of Refresh Dependencies and Refresh Source Folders.
Note that dependencies between projects and source folder configuration are
stored in your project's metadata (the .classpath file). This means they
will persist across Eclipse sessions.
Since 2.7.M2 the contents of the classpath container is also
persisted in your workspace metadata. This reduces the time it takes
for the IDE to become responsive when it starts up. However, it means
you may need to manually trigger a refresh once in a while. You can
tell whether a container
was initialized from persisted state because it will be labeled as
"Gradle Dependencies (persisted)".
Importing Additional Projects
The import wizard is designed to support importing a subset of
subprojects first and, later on, import additional projects as needed.
To import additional projects from the spring-integration project, for
example, simply reopen the import wizard as before and point it again
to
the root of the spring integration project. The project should already
be available from the project combo's pull-down history.
Note
that sub-projects that have been previously imported will not be
shown anymore, since they can't be imported again. An exception to this
rule is made for projects that have subprojects themselves. Such
projects must
be shown because filtering them from the view would also implicitly
remove all their children (making it impossible to import their
children).
The screenshot below shows an "additional import" of the project
"spring-integration-http" in addition to the projects already in the
workspace.

Notice the following in the screenshot:
- The spring-integration-core project and the other previously
imported sub-projects are not shown anymore, so they can not be
imported again.
- The root project "spring-integration" is still shown even
though it was already imported (see above for an explanation why it is
shown). The icon for this project is "ghosted" to indicate it can't be
imported. Should
you attempt to import it anyway, the wizard will show an error message
and disable the "finish" button.
- project "spring-integration-http" is selected. This project
has a dependency on "spring-integration-core". The project is not (and
can not) be selected for import, but the wizard is aware that this
dependency is already satisfied by the projects in the workspace, so it
doesn't show an error for this "missing dependency".
The Task UI: "Launching" Gradle Tasks
In the next section of this tutorial we'll walk through the UI for
creating and launching Gradle launch configurations. Gradle launch
configurations are provided as extensions to the standard Eclipse
launching framework. This means that if you are already familiar with
the Eclipse launch UI, most of this will be familiar to you.
Creating and Executing a Launch
Configuration
Before we can "launch" a list of Gradle tasks, we must create a launch
configuration. The easiest way to do that is by using the "Run As" context menu. This menu is
accessed by right clicking on a Gradle project or one of its nested
resources in the Package Explorer.
The following menu items will be shown (others may also be shown
depending on what exactly you right-clicked on).
Run As >> Gradle Build ... (dots at the end)
This opens a Gradle launch configuration associated
with the
current project in the Tabbed launch configuration editor. This allows
you to examine and edit the configuration before launching it.
If no launch configuration exists yet (for the selected project) an
empty one will be created automatically. If more than one configuration
is found, you will be asked to choose one.
Run As >> Gradle Build (no dots at the end)
This attempts to directly launch a Gradle launch
configuration associated with your project. Typically you would use
this if you already have a launch configuration defined and want to
just launch it without examining or editing it. If a launch
configuration doesn't exist yet, however, one will be created and
opened
in the editor. If more than one
configuration already exists for the selected project, then a dialog
will popup to ask you to choose one.
External Tools Configurations
This opens the generic Eclipse "External Tools
Configurations"
editor, allowing you to create / edit / save etc.
launch configurations of different types, including Gradle launch
configurations.
Since this is our first time launching anything for the spring-integration project, no
launch configuration exists yet. We right click on the root project's
build file (or any other resource in the project) and select "Run As
>> Gradle
Build...". An editor as shown in the screenshot below opens up.

If you have ever used ant launch configurations in Eclipse, the UI
should look familiar since we followed its design. The main difference
is that for Gradle the "list" of available tasks is a tree
rather than just a list. Leaf nodes in the tree are tasks that can be
executed. Internal tree nodes represent sub-projects.
The task tree can be quite large, especially for a project that has
many subprojects. To help in finding a task in a large tree you
can use the "filter text" Box above
the tree. Type in any text, and only the tasks with a name starting
with
this text will be shown. You can add a "*" to the front of your search
pattern to search for substrings instead of prefixes instead. The
screenshot below shows how we filtered the tree to only show "build"
related tasks. We then selected the "build" task in the root project.
Task execution order
If
multiple tasks are selected, the ordering of the tasks is often
important. For example, if we selected both ":clean" and ":build" we
probably want to
make sure that the ":clean" task gets executed before the ":build" task.
The bottom portion of the "Gradle Tasks" Tab shows and controls task
execution order. To change the execution order click the "Order..." Button.
Finally, after reordering the tasks as desired, click on the "Run" Button to save any changes
you have made and launch the configuration.
Alternatively you can use the "Apply"
Button to save the configuration without launching; or the "Close" Button to close it without
launching or saving.
After clicking "Run" the selected tasks will be executed and the
resulting output is displayed in the Eclipse
console view.

Automatically Refreshing the
Workspace after Task Execution
Typically, executing a set of Gradle tasks will cause changes to the
resources in your workspace. Eclipse, by default, will not become aware
of these changes. To make Eclipse aware that underlying resources in
the file system have changed you need to "refresh" the workspace, or at
least the portion of the workspace that you think may have changed. You
can do this manually by using the context menu of any resource in the
workspace. However, it is probably more convenient to automate this.
In the future the Gradle Task API aims to provide explicit information
to the IDE about potential workspace changes. Presently, however, this
is not the case and it is your
responsibility to either manually refresh the resources or
specify which resources should be
refreshed automatically. The Gradle launch configuration editor
provides a standard Eclipse "Refresh" tab to specify an automatic
refresh strategy.

To enable automatic refresh, check the
"Refresh resources upon completion" Checkbox and pick one of the
provided strategies.
Relaunching an Existing (Gradle)
Launch Configuration
After having created a launch configuration, you may want to launch
that same configuration again, either with or without changes.
There are a number of different ways that you can do this. Besides
using the already discussed context menus, you can also use the External Tools Toolbar button

You can either click on the toolbar button itself or use its pull-down
menu.
The pull down menu gives you access to a
list of recent launches (automatically maintained) and a list of favorites (explicitly
managed by you).
Clicking the button (instead of the pulldown) is a shortcut to relaunch the most recent entry in the
history.
Bugs and Feature Requests:
This release should still be considered
experimental. It has been tested with a few
real projects (spock, spring-integration), but we are sure problems and issues remain. We welcome feedback and bug
repors at
Below is a list of
current limitations that we know about.
Project Natures
For the first implementation, we focussed on "pure"
Java projects. In Eclipse terms, this means projects that only require
a Java nature. The tools may or may not work well if you try to apply
them to projects that require non-java natures to be configured (e.g.
WTP projects, Groovy projects, Scala projects, etc.). Whether or not
the tools will work for such projects will depend a lot on the
specifics of how those projects have been setup and configured already
before you import them using our import wizard.
This limitation is mostly because we wanted to narrow
down
the first release to a basic and manageable set of features. Similarly,
the Gradle Tooling API upon which we build only
provides info on things such as a project's classpath, source folders
and inter-project dependencies. These configuration properties of your
projects are
automatically configured by the STS-Gradle plugins.
In the future we hope to expand on the types of projects and
configurations that are explicitly supported. Input from
you, the user (or potential user) is invaluable. Therefore we hope that
even if your specific type of project is not explicitly supported
(yet), you may want to try the tools. We would be very interested to
learn if, where and how exactly the tools break down for you. This
information will help us greatly in prioritizing features to expand on
in the near future.