title: How do I create a jar with all dependencies using Gradle 4.4?
body: <p>This question is related to <a href="https://stackoverflow.com/a/4894308/6296561">this one</a> -- however, due to the deprecation of <code>compile</code> in favor of <code>implementation</code>, it doesn't work. It does pick up dependencies that are declared with <code>compile</code>. However, with it being deprecated, using it isn't an option (and we'd be right back here when it's removed anyway)</p>
  <hr />
  <p>I got this Gradle task:</p>
  <pre class="lang-groovy prettyprint-override"><code>task fatJar(type: Jar) {
      manifest {
          attributes 'Implementation-Title': 'rpi-sense-hat-lib',
                  'Implementation-Version': version,
                  'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
      }
      baseName = project.name
      from { 
          configurations.compile.collect {
              it.isDirectory() ? it : zipTree(it)
          }
      }
      with jar
  }
  </code></pre>
  <p>And there's just one dependency, looking aside test dependencies:</p>
  <pre class="lang-groovy prettyprint-override"><code>dependencies {
      implementation &quot;org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version&quot;
      testImplementation group: 'junit', name: 'junit', version: '4.12'
  }
  </code></pre>
  <p>Running from the IDE works fine. However, when I deploy to my Raspberry Pi (or use the jar <code>gradlew fatJar</code> results in locally), I get this exception:</p>
  <pre class="lang-none prettyprint-override"><code>$ java -jar java-sense-hat-1.0a.jar
  Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
      at io.github.lunarwatcher.pi.sensehat.UtilsKt.getSenseHat(Utils.kt:18)
      at io.github.lunarwatcher.pi.sensehat.SenseHat.&lt;init&gt;(SenseHat.java:12)
      at io.github.lunarwatcher.pi.sensehat.Tests.main(Tests.java:9)
  Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
      at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
      at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
      at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
      ... 3 more
  </code></pre>
  <p>Which is triggered by this line:</p>
  <pre class="lang-java prettyprint-override"><code>return Optional.empty()
  </code></pre>
  <p>in a Kotlin method returning an <code>Optional&lt;File&gt;</code>. <a href="https://stackoverflow.com/a/44734211/6296561">Answer on related question</a>:</p>
  <blockquote>
  <p>Either kotlin-runtime has to be in classpath and verify with $ echo $CLASSPATH.</p>
  <p>Or you have to add kotlin-runtime to maven and then assemble inside the jar itself with mvn compile assembly:single,</p>
  </blockquote>
  <p>Which means the kotlin-runtime isn't included in the classpath. Before you go ahead and answer &quot;add kotlin-runtime to your dependencies&quot;, it's a part of the <a href="https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-runtime" rel="nofollow noreferrer">stdlib</a>:</p>
  <blockquote>
  <p>Kotlin Runtime (deprecated, use kotlin-stdlib artifact instead)</p>
  </blockquote>
  <p>I use <code>kotlin-stdlib-jdk8</code> and it works in the IDE. Just for testing purposes, using <code>kotlin-stdlib</code> instead does not change anything.</p>
  <p>In addition, replacing <code>implementation</code> with <code>compile</code> fixes it.</p>
  <p>In the post I linked at the top of the question, there's a suggestion to use <code>runtime</code> in the fatJar task. So:</p>
  <pre class="lang-groovy prettyprint-override"><code>task fatJar(type: Jar) {
      manifest {
          attributes 'Implementation-Title': 'rpi-sense-hat-lib',
                  'Implementation-Version': version,
                  'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
      }
      baseName = project.name
      from {
          configurations.compile.collect {
              it.isDirectory() ? it : zipTree(it)
          }
          configurations.runtime.collect {
              it.isDirectory() ? it : zipTree(it)
          }
      }
      with jar
  }
  </code></pre>
  <p>The dependency is still not included, and the program crashes.</p>
  <p>So why not add implementation as a configuration to copy from?</p>
  <p>I tried. I ended up with this:</p>
  <pre class="lang-groovy prettyprint-override"><code>task fatJar(type: Jar) {
      manifest {
          attributes 'Implementation-Title': 'rpi-sense-hat-lib',
                  'Implementation-Version': version,
                  'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
      }
      baseName = project.name
      from {
          configurations.compile.collect {
              it.isDirectory() ? it : zipTree(it)
          }
          configurations.runtime.collect {
              it.isDirectory() ? it : zipTree(it)
          }
          configurations.implementation.collect {
              it.isDirectory() ? it : zipTree(it)
          }
      }
      with jar
  }
  </code></pre>
  <p>And an exception:</p>
  <blockquote>
  <p>Resolving configuration 'implementation' directly is not allowed</p>
  </blockquote>
  <p>So, considering:</p>
  <ul>
  <li><code>compile</code> instead of <code>implementation</code> works</li>
  <li>The runtime exception is from Kotlin not being in the classpath</li>
  <li>It works in the IDE</li>
  <li>Adding an <code>implementation</code> clause to the <code>fatJar</code> task crashes the compiling with a separate exception</li>
  </ul>
  <p>How do I generate a jar with all dependencies in Gradle 4.4 when using the <code>implementation</code> keyword?</p>