Basic GradleRIO question on dependencies

We have a test project built using VSCode and GradleRIO using a number of Java classes. I am still learning about Gradle, and my question is about third-party jars referenced in the build.gradle file, as such…

dependencies {
compile pathfinder()
compile wpilib()
compile ctre()
compile navx()
}

Everything is building successfully on a ./gradlew build, so the libraries are evidently fetched and are present. I am trying to understand where these libraries are and what form they take, because I don’t see jars anywhere in the project folder. I do see a number of DLL files in the build/tmp directory for the project:
wpilibJNI.dll
wpihal.dll
etc

(version of Gradle we are using is 4.4)

FYI, I did do a lot of reading on Gradle dependencies here:
https://docs.gradle.org/current/userguide/declaring_dependencies.html

Any pointers/advice would be great - thanks!

Looks like dependency JARs are stored in

~/.gradle/caches/modules-2/files-2.1/

Hi Rob,

First off, thanks for your opening post. It indirectly helped me figure out how to fix a classpath problem with the code the team just ported over to VSCode from Eclipse. We were getting a build error stating that the compiler could not find the Pathfinder library. I noticed in your post that the “compile pathfinder()” statement was in your dependencies, and when we added it that cleared the build error.

Now I find myself asking the same question you did. How did the “compile pathfinder()” statement resolve the classpath issue to find the Pathfinder library? Were you able to figure out anything more on this topic? I’ll keep reading, but I am a tad bit mystified at the moment. Back when we were using Eclipse there was a .classpath file that clearly listed the directory where the libraries (e.g. pathfinder) could be found, but now that we are using Gradle and VSCode I don’t see such an entry in any of the files.

Thanks,
Chris

Gradle uses the Maven style of dependency resolution. Instead of having all the libraries you use in a single directory in your project or floating around your filesystem, you tell it what libraries you want to depend on, where those libraries are available, and when they should be used (e.g. when compiling, only at runtime, only when running tests, etc.).

So what does the “compile pathfinder()” line do?

“compile” tells the build system that the library it’s given is required for the project to compile and run. There are other instructions like “runtime” that means the library is required for the project to run, but not needed at compile time; and “compileOnly” for libraries only needed to compile, but aren’t needed on the runtime classpath.

The “pathfinder()” method is basically an alias for a dependency on Jaci’s pathfinder library. In typical Gradle projects, depending on the pathfinder library would roughly look something like this:


compile group: 'jaci.pathfinder', name: 'Pathfinder-Java', version: '1.8'
runtime group: 'jaci.pathfinder', name: 'Pathfinder-JNI', version: '1.8'

This line will only tell the build system what library to use - it does not tell it where to find the JAR file, source code, javadocs, etc. At build time, Gradle will search for the library in a local cache - this is what timtim17 posted above. If the library isn’t cached, then Gradle will look for it in the available Maven repositories. GradleRIO automatically makes the WPILib maven servers available.

For example, if you want to depend on gauva - a very popular Java library with lots of different quality-of-life utilities - your build.gradle file would look like


repositories {
  mavenCentral()
}

dependencies {
  compile group: 'com.google.guava', name: 'guava', version: '27.0-jre'
}

Gradle will also automatically pull in all the libraries that guava depends on.

With the Ant/Eclipse build system that we used to have, you would need to track down the guava JAR, put it in the libs folder, then do the same for every library that guava uses, and for all the libraries that those libraries need, and so on. This is a huge pain and is called “JAR hell” if you forget to add a JAR file, or worse, use the JAR from an incompatible version of the library.


Side note: the convenience methods “wpilib()”, “ctre()”, and “navx()” are similar to “pathfinder()” in that they all add a bunch of dependencies for the libraries you want to use without needing to keep track of their real names, locations, and version numbers.

How do we build using gradle when the dependencies can’t be downloaded? In our school district internet the filters are blocking the jar downloads for a java build. I could also see a problem at competition of either not having internet or having filtered internet. I tried the zipped VSCode with a data folder to make it portable, built robot code at home with unfiltered internet, tried a build back at school but it failed because it couldn’t download dependencies. What workarounds for internet filtering are there?

Thank you,

Sam Alexander
Team 1290

Most of your builds can be done in “offline” mode where connectivity isn’t necessary. From the command line, just append “–offline” to your gradle command. Eclipse, IntelliJ, and VS Code have offline functions. When the WPILib tools are released in January, there will be a WPILib command palette that sets you up for offline.

By default, gradle tries to pull in the most recent dependencies regularly. However, most of your dependencies will rarely change. Your first build must be online so you can get those dependencies. After that (and especially at competitions) you can mostly be offline.