We are transitioning to Gradle 8. Most things work on Gradle 8. If you want to be safe, stay on the latest version of Gradle 7.
If your OS is setup to automatically update to the latest Gradle version, you'll need to switch to a pinned version or install a version of Gradle 7 manually.
Gradle is an open-source build automation tool focused on flexibility and performance. Gradle build scripts are written using a Groovy or Kotlin DSL. Read about Gradle features to learn what is possible with Gradle.
The ihmc-build
plugin configures Gradle in a unique way in order to address lab specific needs. It is required to read the IHMC Build Plugin README to become familiar with its structure.
Gradle official documentation: https://docs.gradle.org/current/userguide/userguide.html
This guide assumes you have installed Java.
It is required to read and at least partially understand the Gradle official documentation on its Build Environment.
Installation
Please refer to the official Gradle Installation guide. The important things to keep in mind are:
- Make sure you understand how to upgrade to the latest version.
- Install the source code too. This will allow your IDE to help you more.
- Know where Gradle is installed. Specifically, know the path of the "home" directory. (The one that contains the
bin
,lib
andsrc
folders.) You need to paste this into your IDE configuration. - Have a command line environment in which you can invoke
gradle -version
.- If you have manually installed Gradle, this means you will need to add
<gradle_home>/bin
to yourPATH
or placing a symbolic link somewhere in the system path.
- If you have manually installed Gradle, this means you will need to add
Manual Installation
If you are unsatisfied with the recommended installation methods, you may choose to install Gradle manually. Reasons for this are:
- You are on Windows and are unsatisfied with Chocolately.
- You are on Ubuntu and the system provided Gradle package is out-of-date.
- You don't want to learn how to use SDKMAN!, Homebrew, or Chocolately.
Manual installation steps:
- Download an
*-all
or "complete" distribution zip from https://services.gradle.org/distributions/ or https://gradle.org/releases/- Make sure the zip file contains
bin
andsrc
- Make sure the zip file contains
- Unzip the distribution
- Linux command:
unzip gradle.zip -d gradle
- Linux command:
- Copy the distribution to a suitable system directory.
- Windows suggested:
C:\gradle-7.5.1
- Linux suggested:
/opt/gradle-7.5.1
- Windows suggested:
- Create a version-less symbolic link. This makes it easy to upgrade. Use the link in
PATH
and in IDEs.- Unix command:
ln -s /opt/gradle-7.5.1/ /opt/gradle
- Windows command:
mklink C:\gradle
C:\gradle-7.5.1
- Unix command:
- Add Gradle
bin
folder to thePATH
environment variable.- Linux: Add
export PATH=$PATH:/opt/gradle/bin
to~/.bashrc
- Linux: Add
Example commands on a Unix system:
$ cd ~/Downloads $ curl -sL https://services.gradle.org/distributions/gradle-7.6.1-all.zip -o gradle.zip $ unzip -q gradle.zip -d gradle # mv gradle/gradle-7.6.1/ /opt/. # rm /opt/gradle # ln -s /opt/gradle-7.6.1/ /opt/gradle # rm /usr/bin/gradle # ln -s /opt/gradle/bin/gradle /usr/bin/gradle
Verify installation:
$ gradle -v ------------------------------------------------------------ Gradle 7.6.1 ------------------------------------------------------------
SDKMAN! Installation
Alternatively will can use SDKMAN! which is a package manager for Gradle, Java, and many other frameworks on Ubuntu.
See the page on SDKMAN!
Now install Gradle:
sdk install gradle 7.6.1
Note, Gradle will be installed in a hidden folder located at (You may have to press Ctrl + H to view hidden folders in Ubuntu's file explorer):
~/.sdkman/candidates/gradle/7.6.1
Configuration
If you have not yet read the Gradle official documentation on the Build Environment, please do so now. This section will mostly contain the important highlights of that document. Gradle properties files are .properties files.
User home gradle.properties
file
- Navigate to your user home directory.
- Show hidden files.
- Ensure the existence of the file
~/.gradle/gradle.properties
on Ubuntu orC:/Users/<user>/.gradle/gradle.properties
on Windows. - If it is not there, create it manually. This file's settings will override project and system level settings.
Nexus credentials
Though most IHMC software is freely available, the proprietary parts will require an IHMC Crowd account. To authenticate, the ihmc-build
plugin loads these credentials as Gradle properties. Set them:
nexusUsername=robotlab-devs nexusPassword=<password>
You can retrieve the nexus password from 1Password.
NOTE: Bintray and Artifactory are both deprecated, and do not need to be set in your gradle.properties
file.
You can also use your personal IHMC credentials (same as what you use to login to wifi)
nexusUsername=<your wifi username> nexusPassword=<your wifi password>
Selecting a JVM
To select the JVM that Gradle runs itself with, set JAVA_HOME
. (This is the version shown with gradle --version
)
To select the JVM that Gradle runs your build code with, set org.gradle.java.home
. On Windows, you will need to use forward slashes "/" instead of backslashes "\". (see here)
org.gradle.java.home=/usr/lib/jvm/java-8-openjdk # Linux example org.gradle.java.home=C:/Program Files/Java/jdk-17.0.3 # Windows example
Optimizing JVM memory for better performance
Large workspaces require setting "Xmx" to 2 or 3 gigabytes.
The org.gradle.jvmargs
Gradle property controls the VM running the build. See Configuring JVM Memory.
Typical options:
- "-Xms" - The initial memory allocated, increasing this can improve startup times, but if running many builds at once, is bad
- "-Xmx" - Max memory allowed, increasing this can allow larger caches and less garbage collects, increasing performance
- "-Dfile.encoding" - Set to
UTF-8
to unify experince over multiple platforms - "-Dpython.console.encoding=UTF-8" - On Windows, fixes error
Working examples:
Windows:
IHMC Employees:
nexusUsername=<your wifi username>
nexusPassword=<your wifi password>
org.gradle.java.home=C:/Program Files/Java/jdk-17.0.3.1
org.gradle.jvmargs=-Xmx4g
Open Source Only:
org.gradle.java.home=C:/Program Files/Java/jdk-17.0.3.1
org.gradle.jvmargs=-Xmx4g
Ubuntu:
IHMC Employees:
nexusUsername=<your wifi username>
nexusPassword=<your wifi password>
org.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64
org.gradle.jvmargs=-Xmx4g
Open Source Only:
org.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64
org.gradle.jvmargs=-Xmx4g
Working with Gradle
Running Gradle on the command line
It is extremely handy to be prepared to run Gradle from the command line. This requires a Gradle installation. You should be able to, at the very least run
gradle --version
See the official documentation on the Gradle Command-Line Interface and the IHMC Build Plugin README for details.
The most common debugging strategy is to simply configure the build with --info
and --stacktrace
enabled. This strategy can be used to isolate problems from your IDE.
~/dev/repository-group $ gradle --info --stacktrace
Knowing if the above command results in "BUILD SUCCESSFUL" or "BUILD FAILED" greatly shrinks the scope of search for a Gradle problem.
Importing into an IDE
Importing Gradle projects into an IDE is very similar to running Gradle on the command line. When you import a Gradle project you are entering the Gradle Build Environment. When you import a Gradle project, the IDE is analyzing the Java build structure that Gradle comes up with and copying that configuration into it's own data structures as if you had painstakingly configured a new Java project manually.
- IntelliJ - See IntelliJ IDEA#ImportingGradleProjects
- Eclipse - See Eclipse IDE
Refreshing IDE configuration
When you refresh a Gradle project in an IDE, the IDE is analyzing the updated Java build structure that Gradle comes up with and copying that configuration into it's own data structures as if you had painstakingly configured the Java projects manually. To trigger a refresh:
- In Eclipse - Right click any project in the Project Explorer that has the little elephant icon. "Right Click > Gradle > Refresh Gradle Project" will refresh the build that that project came from.
- Keep in mind that in Eclipse, it is possible to import multiple Gradle builds. Once imported, there is no way to see the list of what you have imported. Therefore, you must keep track of this yourself to know which projects you mught right-click in order to refresh your entire workspace.
- In IntelliJ - Click the refresh icon in the Gradle view.
Changing project dependencies
Project dependencies are contained in the dependencies
block in the build.gradle
file for that project.
When using the ihmc-build
plugin, there is a dependencies block for each source set. i.e. mainDependencies
, testDependencies
, etc.
You can find new dependencies on Maven Central, JCenter, or Bintray. You can also depend on other IHMC software.
Refer to the IHMC Build Plugin README.
Difference between build.gradle
and build.gradle.kts
files
Gradle was originally written using Groovy but has now adopted the Kotlin language. Kotlin is preferred due to its strong typing system. Strong typing allows linking to source code, documentation, and auto-completing code.
Gradle files ending in .kts
are written in Kotlin instead of Groovy. For more information, see the official Gradle Kotlin DSL Primer.
IntelliJ has much better support for editing Gradle files than Eclipse.
The ihmc-build
plugin has experimental support for .kts
files.
Troubleshooting
Debugging Gradle builds
First, read Running Gradle on the command line.
The first thing to find out is if Gradle configures without errors. Gradle configuration is invoked with the gradle
command without any arguments. Adding --info
and --stacktrace
can give you necessary debugging information. The --debug
option is extremely verbose and it mostly only helpful for plugin developers.
Logging output to a file
It is often helpful to log Gradle build output to a file. To do this, run
gradle --info --stacktrace &> log.txt // simple way gradle --info --stacktrace 2>&1 | tee ~/.ihmc/logs/$(date +%Y%m%d%k%M%S)_build.txt // see the output on the console for monitoring and store the log in the logs folder
Windows users see Windows#Logtoafile(butalsotoconsole) to install the tee
command.
Unresponsive Builds
If a build is hanging it may be necessary to stop the process with Ctrl+C
and stop all running Gradle daemons with gradle --stop
. If that doesn't work, try running with --no-daemon
.
Getting help
It is sometimes very difficult to understand why Gradle is failing. You can get help in the #help-desk
Slack channel. Guidelines for help requests:
- When there is an error in text, please copy the full error message into the chat instead of only providing a screenshot. This helps others search for help.
- Upload a log.txt (see "Logging output to a file" section above).
Problems with ppa:cwchien/gradle
Though we no longer recommend using it, use of the cwchien PPA is still installed on many computers running IHMC software.
Using it, it is sometimes necessary to completely remove Gradle and reinstall in order to upgrade. In some cases, an apt autoremove
might even be necessary.
Please remove it and reinstall.
Dependency Troubleshooting
(Note: On Windows, first install tee.exe)
Run the following command in your workspace directory. This would most likely be ~/dev/repository-group
.
gradle --info compositeTask -PtaskName=dependencies 2>&1 | tee ~/.ihmc/logs/$(date +%Y%m%d%k%M%S)_dependencies.txt gradle --info dependencies 2>&1 | tee ~/.ihmc/logs/$(date +%Y%m%d%k%M%S)_dependencies.txt # if not using ihmc-build
Then use an interactive text editor such as Notepad++ to search for dependency occurrences.
Gradle's dependency resolution algorithm is explained in detail here.
Compile Error Troubleshooting
Test if Gradle can compile your workspace on the command line:
gradle --info compositeTask -PtaskName=compileJava
See more in the IHMC Build plugin README.
Exclude Modules in Main Dependencies
If you want to exclude a specific module from a main dependency, go to your build.gradle file and in your mainDependencies block, edit the dependency to have the following format.
api("SOME_MAIN_DEPENDENCY") { exclude("SOME_GROUP:SOME_MODULE") }