Nowadays, it’s quite easy to have access to an embedded linux installation under Windows, allowing to use command line tools (like maven or gradle) right from that terminal.

One problem still remains : everything executed inside that local shell installation will have absolute paths, not known by windows. This is going to be problematic when one is willing to use gradle in the terminal and eclipse under windows, as the generated .classpath files will by default have absolute paths, not understandable by eclipse. This can however be corrected by changing :

  • 1. the gradle home user location (in order to store cached dependencies in the windows filesystem, most of the time ~/.gradle)
  • 2. the gradle build files (in order for the absolute paths to be replaced by a variable, GRADLE_HOME)
  • 3. the eclipse installation (in order for eclipse to know that new GRADLE_HOME variable)

Note : for years, when working under windows, i was using cygwin, but the expererience was less straightforward.

Prerequesite - How to install WSL under windows

Just follow that kind of tutorials in order to activate WSL (bash.exe) under Windows : How to install the linux bash shell on windows 10

Then pick up a distribution from the Microsoft Store, for example Debian.

How to work on windows with gradle and WSL (windows bash) media/screenshots/screenshot-microsoft-store-linux-wsl-distributions.png

Prerequesite - Best way to access the bash shell

As the cmd.exe terminal is quite inefficient, i’m instead starting a SSH server inside the bash container ; once configured, i can just access my local terminal with any SSH client. Here i’m using Netsarang XShell.

How to work on windows with gradle and WSL (windows bash) /media/screenshots/screenshot-xshell-gradle.png

Links :

Prerequesite - One-liner command to install latest gradle version

As debian is providing a very old gradle version, we want to install the latest one.

Once connected in the windows bash session :

sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y zsh openjdk-8-jdk-headless openjdk-11-jdk-headless git curl wget unzip unrar-free maven
cd /opt && curl -sL 'https://services.gradle.org/distributions/gradle-5.2.1-bin.zip' | sudo jar xvf /dev/stdin && sudo ln -s /opt/gradle-5.2.1/ /opt/gradle && sudo chmod a+x /opt/gradle/bin/gradle

Then add in .bashrc something like (the PATH reconfiguration is mandatory to use the locally installed gradle under the terminal) :

export PATH=.:/opt/gradle/bin/:$PATH
export WORKSPACES=/mnt/e/workspaces/

Step 1 - Customize the gradle home user location

Just put in place an alias in .bashrc, allowing through the --gradle-user-home parameter to have cached dependencies being stored in the regular path under windows (for eclipse to be able to reuse them). Without this parameter, dependencies would be stored inside the WSL installation (and wouldn’t be available for eclipse).

alias gradle='gradle --gradle-user-home /mnt/c/Users/sergio/.gradle'

Step 2 - Customize gradle build files

In order for generated eclipse .classpath to not contain anymore an absolute path, it is mandatory to customize each build.gradle file with the pathVariables string substitution (@see gradle configuration for eclipse plugin) :

// === Eclipse configuration
eclipse {
    pathVariables 'GRADLE_HOME': file('/mnt/c/Users/sergio/.gradle') 
    
    classpath {
        downloadSources = true
        downloadJavadoc = false
    }
}

Step 3 - Customize eclipse

Now we have to tell to eclipse to understand this new GRADLE_HOME variable.

How to work on windows with gradle and WSL (windows bash) media/screenshots/screenshot-eclipse-gradle-home-variable.png

As classpath entries under .classpath are now looking like this :

<classpathentry sourcepath="GRADLE_HOME/caches/modules-2/files-2.1/com.google.guava/guava/25.0-jre/30ade485699e7782cc2369b0e5d3d8e0bfc317c/guava-25.0-jre-sources.jar" kind="var" path="GRADLE_HOME/caches/modules-2/files-2.1/com.google.guava/guava/25.0-jre/7319c34fa5866a85b6bad445adad69d402323129/guava-25.0-jre.jar">
    <attributes>
        <attribute name="gradle_used_by_scope" value="main,test"/>
    </attributes>
</classpathentry>