javamavengradle

Build is successful but the runtime dependency seems bad in Gradle dependency


dependencies {
 compile 'org.slf4j:slf4j-api:1.7.13'
    compile group: 'org.apache.commons', name: 'commons-math3' , version: '+'
    testCompile 'junit:junit:4.12'
}

Even if I add this, when I run gradle build, it works, and codes with commons-math3 can be compiled. But when I run a jar file in build/,

it says Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/math3/complex/Complex

But the official Gradle site says, the resource in 'compile' will also be included in 'runtime' dependency. and I also tried adding the commons-math to runtime. but it does not work.

Maybe this is my misunderstood of the dependency system.

How can I include external library from maven repository into a jar file made by the Gradle.


Solution

  • What you are looking for is either the distribution zips produced by the application plugin or the shadow jar (also called fat jar) produced by the shadowJar plugin:

    The distribution zip (application plugin)

    About the distribution zip

    The distribution zips look like this:

    my-app-0.2.0.zip
    ├──bin
    │  ├──my-app
    │  └──my-app.bat
    └──lib
       ├──my-app-0.2.0.jar
       ├──slf4j-api.1.7.13.jar
       └──commons-math3-3.6.jar
    

    You can then run your application with its dependencies by unzipping what has been produced in build/distributions/ and running either my-app.bat (on windows) or ./my-app (on linux or OS X)

    Building a distribution zip

    Here is a sample gradle build file for making a distribution zip:

    build.gradle

    apply plugin: 'java'
    apply plugin: 'application'
    
    mainClassName = 'org.myapp.Main'
    
    repositories { jcenter() }
    dependencies {
        compile 'org.slf4j:slf4j-api:1.7.13'
        compile 'org.apache.commons:commons-math3:3.6'
    
        testCompile 'junit:junit:4.12'
    }
    

    Can be run with gradle distributionZip or gradle distributionTar. To just run the application, use gradle run.

    The shadow jar

    About the shadow jar

    The shadow jar is one giant jar file that is a combination of your program and its libraries, packed together into one file. You will get a file that is self-contained and can be run by a double-click on most systems (e.g. on Windows that works, on Xubuntu it can be run by right-clicking and selecting 'Run with Oracle Java 8 Runtime', etc...).

    Building a distribution zip

    Here is, again, a sample build.gradle file:

    apply plugin: 'java'
    apply plugin: 'com.github.johnrengelman.shadow'
    
    mainClassName = 'org.myapp.Main'
    
    jar {
        manifest {
            attributes('Main-Class': mainClassName)
        }
    }
    
    buildscript {
        repositories { jcenter() }
        dependencies {
            classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.2'
        }
    }
    
    repositories { jcenter() }
    dependencies {
        compile 'org.slf4j:slf4j-api:1.7.13'
        compile 'org.apache.commons:commons-math3:3.6'
    
        testCompile 'junit:junit:4.12'
    }
    

    Run it with gradle shadowJar - Your jar with packed dependencies will be in build/libs and it will be named my-app-x.x.x-all.jar.