1

I'm not an expert on Java, but I'm trying to build a component to transcribe a podcast, using the CMU Sphinx 4 library. I'm using Eclipse Mars and Gradle to build the project as a runnable fat jar. My build.gradle looks like this.

/*
 * This build file was auto generated by running the Gradle 'init' task
 * by 'peter' at '03/06/16 18:34' with Gradle 2.6
 *
 * This generated file contains a sample Java project to get you started.
 * For more details take a look at the Java Quickstart chapter in the Gradle
 * user guide available at https://docs.gradle.org/2.6/userguide/tutorial_java_projects.html
 */

// Apply the java plugin to add support for Java
apply plugin: 'java'



// In this section you declare where to find the dependencies of your project
repositories {
    // Use 'jcenter' for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
    mavenLocal()
    maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}

// In this section you declare the dependencies for your production and test code
dependencies {
    // The production code uses the SLF4J logging API at compile time
    compile 'org.slf4j:slf4j-api:1.7.12'
    compile group: 'edu.cmu.sphinx', name: 'sphinx4-core', version:'5prealpha-SNAPSHOT'
    compile group: 'edu.cmu.sphinx', name: 'sphinx4-data', version:'5prealpha-SNAPSHOT'

    // Declare the dependency for your favourite test framework you want to use in your tests.
    // TestNG is also supported by the Gradle Test task. Just change the
    // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
    // 'test.useTestNG()' to your build script.
    //testCompile 'junit:junit:4.12'
}

jar {

   manifest {
        attributes (
        'Class-Path': configurations.compile.collect { it.isDirectory() ? it : zipTree(it) },
        'Main-Class': 'org.conlang.sources.transcriber.Transcriber')
    }
    from configurations.compile.collect { entry -> zipTree(entry) }
}

Here is the manifest it produces.

Manifest-Version: 1.0
Class-Path: [ZIP '/home/peter/.gradle/caches/modules-2/files-2.1/org.s
 lf4j/slf4j-api/1.7.12/8e20852d05222dc286bf1c71d78d0531e177c317/slf4j-
 api-1.7.12.jar', ZIP '/home/peter/.gradle/caches/modules-2/files-2.1/
 edu.cmu.sphinx/sphinx4-core/5prealpha-SNAPSHOT/523f86d4932fc124a6d497
 6adbcbc4976f1ece28/sphinx4-core-5prealpha-SNAPSHOT.jar', ZIP '/home/p
 eter/.gradle/caches/modules-2/files-2.1/edu.cmu.sphinx/sphinx4-data/5
 prealpha-SNAPSHOT/545a2d84cfe804d18cd9926a35331546fe09f2c2/sphinx4-da
 ta-5prealpha-SNAPSHOT.jar', ZIP '/home/peter/.gradle/caches/modules-2
 /files-2.1/org.apache.commons/commons-math3/3.2/ec2544ab27e110d2d431b
 dad7d538ed509b21e62/commons-math3-3.2.jar']
Main-Class: org.conlang.sources.transcriber.Transcriber

When I copy and paste to another directory on my own machine, the jar won't run, because Java can't find the paths in the manifest, and it certainly won't run on another machine. What do I have to change in my build.gradle to get a usable ClassPath?

  • Possible duplicate of [Using Gradle to build a jar with dependencies](http://stackoverflow.com/questions/4871656/using-gradle-to-build-a-jar-with-dependencies) – Nikolay Shmyrev Jun 14 '16 at 13:48

2 Answers2

0

How are you distributing dependency jars to keep your package portable?

This it.isDirectory() ? it : zipTree(it) will produce absolute paths of your dependency jars. If you're trying to create a distributable package including dependencies, jar plugin isn't probably the best way, try the application plugin instead.

RaGe
  • 22,696
  • 11
  • 72
  • 104
  • The line from configurations.compile.collect { entry -> zipTree(entry) } in the jar section, just below manifest, adds the dependencies to the jar. This bit is working correctly. – Pete Bleackley Jun 13 '16 at 14:56
  • Your issue is the line in `jar.manifest.attributes.class-path` which is where the absolute paths come from. You can try using `it.name` instead of `it` in the manifest section. – RaGe Jun 13 '16 at 15:34
  • I've tried that, and I've also tried relativePath(it) and relativePath(it.name), but nothing seems to work. I get the same results every time. – Pete Bleackley Jun 13 '16 at 20:37
0

You can simply use

jar {
   manifest {
        attributes (
            'Main-Class': 'org.conlang.sources.transcriber.Transcriber')
    }
    from configurations.compile.collect { entry -> zipTree(entry) }
}

You do not need to specify classpath if you unpack all dependencies with configurations.compile.collect. This is a duplicate of Using Gradle to build a jar with dependencies

Community
  • 1
  • 1
Nikolay Shmyrev
  • 24,897
  • 5
  • 43
  • 87