diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,17 @@
 
 ### Added
 
+## [0.8.0] - 2018-02-27
+
+### Added
+
+* `addJarsToClasspath`: a function to add a list of jar paths to
+  the CLASSPATH in cabal hooks.
+
 ### Changed
+
+* `gradleHooks` now extends the CLASSPATH even if the CLASSPATH is set.
+* Renamed `setGradleClasspath` to `prependClasspathWithGradle`.
 
 ## [0.7.2] - 2017-12-27
 
diff --git a/inline-java.cabal b/inline-java.cabal
--- a/inline-java.cabal
+++ b/inline-java.cabal
@@ -1,5 +1,5 @@
 name:                inline-java
-version:             0.7.2
+version:             0.8.0
 synopsis:            Java interop via inline Java code in Haskell modules.
 description:         Please see README.md.
 homepage:            http://github.com/tweag/inline-java#readme
@@ -42,7 +42,7 @@
     directory >=1.2,
     filepath >=1,
     ghc >=8.0.2 && <8.3,
-    jni >=0.4 && <0.6,
+    jni >=0.4 && <0.7,
     jvm >=0.4 && <0.5,
     language-java >=0.2,
     mtl >=2.2.1,
diff --git a/src/Language/Java/Inline/Cabal.hs b/src/Language/Java/Inline/Cabal.hs
--- a/src/Language/Java/Inline/Cabal.hs
+++ b/src/Language/Java/Inline/Cabal.hs
@@ -10,30 +10,46 @@
 
 module Language.Java.Inline.Cabal
   ( gradleHooks
-  , setGradleClasspath
+  , prependClasspathWithGradle
   , gradleBuild
+  , addJarsToClasspath
   ) where
 
+import Control.Exception (evaluate)
+import Control.Monad (when)
 import Data.Monoid
+import Data.List (intersperse, isPrefixOf)
 import Distribution.Simple
 import Distribution.Simple.Setup (BuildFlags)
 import Distribution.Simple.LocalBuildInfo (LocalBuildInfo)
-import Distribution.PackageDescription (HookedBuildInfo, PackageDescription)
+import Distribution.PackageDescription
 import System.Directory (doesFileExist, getCurrentDirectory)
 import System.Environment (lookupEnv, setEnv)
 import System.FilePath
-import System.IO (hClose)
+import System.IO
 import System.IO.Temp (withSystemTempFile)
 import System.Process (callProcess, readProcess)
 
--- | Adds the 'setGradleClasspath' and 'gradleBuild' hooks.
+-- | Adds the 'prependClasspathWithGradle' and 'gradleBuild' hooks.
+--
+-- Also adds the jar produced by gradle to the data-files.
 gradleHooks :: UserHooks -> UserHooks
 gradleHooks hooks = hooks
-    { preBuild = setGradleClasspath <> preBuild hooks
+    { preBuild = prependClasspathWithGradle <> preBuild hooks
     , buildHook = gradleBuild <> buildHook hooks
-    , preHaddock = setGradleClasspath <> preHaddock hooks
+    , preHaddock = prependClasspathWithGradle <> preHaddock hooks
+    , instHook = instHook simpleUserHooks . addJarToDataFiles
+    , copyHook = copyHook simpleUserHooks . addJarToDataFiles
+    , regHook = regHook simpleUserHooks . addJarToDataFiles
     }
 
+-- | Prepends the given jar paths to the CLASSPATH.
+addJarsToClasspath :: [FilePath] -> UserHooks -> UserHooks
+addJarsToClasspath extraJars hooks = hooks
+    { preBuild = setClasspath extraJars <> preBuild hooks
+    , preHaddock = setClasspath extraJars <> preHaddock hooks
+    }
+
 gradleBuildFile :: FilePath
 gradleBuildFile = "build.gradle"
 
@@ -58,25 +74,67 @@
         -- trim trailing newlines
         >>= return . concat . lines
 
--- | Set the @CLASSPATH@ from a Gradle build configuration. Does not override
--- the @CLASSPATH@ if one exists.
-setGradleClasspath :: Args -> b -> IO HookedBuildInfo
-setGradleClasspath _ _ = do
+-- | Prepends the @CLASSPATH@ with the classpath from a Gradle build
+-- configuration.
+prependClasspathWithGradle :: Args -> b -> IO HookedBuildInfo
+prependClasspathWithGradle _ _ = do
     here <- getCurrentDirectory
     origclasspath <- lookupEnv "CLASSPATH"
-    case origclasspath of
-      Nothing -> do
-        mbbuildfile <- findGradleBuild here
-        case mbbuildfile of
-          Nothing -> fail $ unwords [gradleBuildFile, "file not found in", here]
-          Just buildfile -> do
-            classpath <- getGradleClasspath buildfile
-            setEnv "CLASSPATH" classpath
-      Just _ -> return ()
+    mbbuildfile <- findGradleBuild here
+    case mbbuildfile of
+      Nothing -> fail $ unwords [gradleBuildFile, "file not found in", here]
+      Just buildfile -> do
+        classpath <- getGradleClasspath buildfile
+        setEnv "CLASSPATH" $ classpath ++ maybe "" (':':) origclasspath
     return (Nothing, [])
 
+setClasspath :: [FilePath] -> a -> b -> IO HookedBuildInfo
+setClasspath extraJars _ _ = do
+    mclasspath <- lookupEnv "CLASSPATH"
+    setEnv "CLASSPATH" $
+      concat $ intersperse ":" $
+        maybe extraJars (\c -> extraJars ++ [c]) mclasspath
+    return (Nothing, [])
+
 -- | Call @gradle build@ as part of the Cabal build. Useful to e.g. build
 -- auxiliary Java source code and to create packages.
 gradleBuild :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
-gradleBuild _ _ _ _ = do
+gradleBuild pd _ _ _ = do
+    setProjectName
     callProcess "gradle" ["build"]
+  where
+    settingsFile = "settings.gradle"
+
+    setProjectName :: IO ()
+    setProjectName = do
+      missingProjectName <- isProjectNameSet
+      when missingProjectName $
+          appendFile "settings.gradle" $
+            "\nrootProject.name = '" ++
+            unPackageName (pkgName (package pd)) ++ "'\n"
+
+    isProjectNameSet :: IO Bool
+    isProjectNameSet = do
+      exists <- doesFileExist settingsFile
+      if not exists
+      then return True
+      else withFile settingsFile ReadMode $ \h -> do
+             b <- any ("rootProject.name =" `isPrefixOf`) . lines
+               <$> hGetContents h
+             -- If we don't evaluate the boolean before returning, the
+             -- file handle will be closed when we try to read the file.
+             evaluate b
+
+-- "<pkgname>.jar" is a file build by gradle during building. This file needs
+-- to be installed together with the library, otherwise it wouldn't be available
+-- to build other code depending on it. Therefore, we add the jar to the field
+-- dataFiles in the hooks instHook, copyHook and regHook. This way the jar is
+-- installed, but cabal does not account it when deciding if the package needs
+-- to be rebuilt.
+
+addJarToDataFiles :: PackageDescription -> PackageDescription
+addJarToDataFiles pd = pd
+    { dataFiles =
+        ("build/libs" </> unPackageName (pkgName (package pd)) <.> "jar")
+        : dataFiles pd
+    }
diff --git a/src/Language/Java/Inline/Magic.hsc b/src/Language/Java/Inline/Magic.hsc
--- a/src/Language/Java/Inline/Magic.hsc
+++ b/src/Language/Java/Inline/Magic.hsc
@@ -16,7 +16,6 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# OPTIONS_GHC -ddump-ds #-}
 
 module Language.Java.Inline.Magic
   ( DotClass(..)
diff --git a/src/Language/Java/Inline/Plugin.hs b/src/Language/Java/Inline/Plugin.hs
--- a/src/Language/Java/Inline/Plugin.hs
+++ b/src/Language/Java/Inline/Plugin.hs
@@ -36,7 +36,7 @@
 import TyCoRep
 import TysWiredIn (nilDataConName, consDataConName)
 import System.Directory (listDirectory)
-import System.FilePath ((</>), (<.>))
+import System.FilePath ((</>), (<.>), takeDirectory)
 import System.IO (withFile, IOMode(WriteMode), hPutStrLn, stderr)
 import System.IO.Temp (withSystemTempDirectory)
 import System.Process (callProcess)
@@ -93,7 +93,9 @@
     -- command line without saying -package inline-java.
     bctable_header :: String
     bctable_header = $(do
-        let f = "cbits/bctable.h"
+        loc <- TH.location
+        let root = iterate takeDirectory (TH.loc_filename loc) !! 5
+            f = root </> "cbits/bctable.h"
         TH.addDependentFile f
         TH.lift =<< TH.runIO (readFile f)
       )
