diff --git a/.travis.yml b/.travis.yml
index c95d22ba6520a15b8a146ada423d3dfb1df590c2..29500433dfd6c17f25f9cf785b692119cde28575 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,6 @@ language: java
 
 jdk:
   - oraclejdk9
-  - openjdk8
 
 matrix:
   include:
@@ -10,18 +9,23 @@ matrix:
       addons:
         sonarcloud:
           organization: "i2p"
+      before_install:
+        - export JAVA7_HOME=$(jdk_switcher home openjdk7)
+        - sed -i "1iplugins {\n    id 'org.sonarqube' version '2.6.1'\n}\n" build.gradle
+    - jdk: openjdk8
+      before_install:
+        - export JAVA7_HOME=$(jdk_switcher home openjdk7)
     - jdk: openjdk7
       sudo: required
       before_install: # Work around missing crypto in openjdk7
+        - export JAVA7_HOME=$(jdk_switcher home openjdk7)
         - sudo wget "https://bouncycastle.org/download/bcprov-ext-jdk15on-158.jar" -O "${JAVA_HOME}/jre/lib/ext/bcprov-ext-jdk15on-158.jar"
         - sudo perl -pi.bak -e 's/^(security\.provider\.)([0-9]+)/$1.($2+1)/ge' /etc/java-7-openjdk/security/java.security
         - echo "security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider" | sudo tee -a /etc/java-7-openjdk/security/java.security
-
-before_install:
- - |
-    if [ "$TRAVIS_JDK_VERSION" == "oraclejdk8" ]; then
-      sed -i "1iplugins {\n    id 'org.sonarqube' version '2.6.1'\n}\n" build.gradle
-    fi
+      install:
+        - export TARGET_JAVA_HOME=$JAVA_HOME
+        - jdk_switcher use oraclejdk8
+        - ./gradlew assemble
 
 before_cache:
   - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
diff --git a/build.gradle b/build.gradle
index cd78dc358992f5be9abb1dcc799807e8eb88406e..eb0439251506ae366d011f1c2fb9454b366fe1d9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -40,6 +40,15 @@ String compat(String src) {
     }
 }
 
+String javaExecutable(String targetJavaHome, String execName) {
+    def javaExecutablesPath = new File(targetJavaHome, "bin")
+    def executable = new File(javaExecutablesPath, execName)
+    if (!executable.exists()) {
+        throw new IllegalArgumentException("There is no ${execName} executable in ${javaExecutablesPath}")
+    }
+    executable.toString()
+}
+
 def releaseVersion = getReleaseVersion()
 def buildVersion = getBuildVersion()
 def buildExtra = getBuildExtra()
@@ -98,6 +107,36 @@ configure(javaProjects) {
             options.compilerArgs.addAll(['--release', version])
         }
     }
+
+    // Set up Java override if configured (used to test with Java 7).
+    def targetJavaHome = System.getenv("TARGET_JAVA_HOME")
+    if (targetJavaHome) {
+        if (JavaVersion.current().java9Compatible) {
+            throw new GradleException("Only set TARGET_JAVA_HOME with JDK 8")
+        }
+
+        project.afterEvaluate {
+            logger.info("Target Java home set to ${targetJavaHome}")
+            logger.info("Configuring Gradle to use forked compilation and testing")
+
+            tasks.withType(JavaCompile) {
+                options.fork = true
+                options.forkOptions.javaHome = file(targetJavaHome)
+            }
+
+            tasks.withType(Javadoc) {
+                executable = javaExecutable(targetJavaHome, "javadoc")
+            }
+
+            tasks.withType(Test) {
+                executable = javaExecutable(targetJavaHome, "java")
+            }
+
+            tasks.withType(JavaExec) {
+                executable = javaExecutable(targetJavaHome, "java")
+            }
+        }
+    }
 }
 
 task codeCoverageReport(type: JacocoReport) {