How to include dependencies in jar?


(Nikecow) #1

Hello,

I have a project which requires the JNA libraries on runtime. I included compile group: ‘net.java.dev.jna’, name: ‘jna-platform’, version: ‘4.2.2’ in my gradle.build file and everything compiles fine.

However, when I open the jar I get a NoClassDeffounderror error because the JNA library is nowhere to be found in the jar. How can I make sure the libraries are also available in the jar itself? Here is my build.gradle:

plugins {
    id "groovy"
    id "java"
    id "idea"
}

//Grade attributes
group 'com.nikecow'
version '0.1'

task wrapper(type: Wrapper) {
    gradleVersion = "3.0";
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.7'
    compile group: 'net.java.dev.jna', name: 'jna-platform', version: '4.2.2'
    testCompile group: 'junit', name: 'junit', version: '+'
}

(Janito Vaqueiro Ferreira Filho) #2

You might be interested in using the Shadow plugin. It generates a “fat-jar”, which is a Jar with the necessary dependencies. Note that the plugin creates a new task shadowJar to generate the “fat-jar”.

Hope this helps :slight_smile:


(Nikecow) #3

Hey thank you that worked.

Howevever, I am very surprised gradle offers no native functionality for this.
I thought managing dependencies was the entire purpose of gradle. Very confusing.

Anyone knows why this is?


(davidmichaelkarr) #4

First of all, the default jar that Gradle produces will only contain the classes compiled from the source code in the project. It would be counterproductive to always include all of the dependencies in that jar because depending on the deployment environment, those dependencies would already be provided. If you were using the “war” plugin, those dependencies would be included in the WEB-INF/lib.

Second, concerning why the Shadow plugin isn’t provided “natively” in Gradle, the Gradle core is intentionally minimal because different people have different ideas about what they need for their build, and there are widely differing needs. The rich plugin ecosystem that Gradle provides and supports makes this possible.


(Nikecow) #5

Hi David,

Thanks for your answer. It’s just that for a rookie like me it is very confusing that the program works fine in the IDE, but once it is compiled into a jar it is missing dependencies.

Fortunately I have solved my issue without the usage of external plugins. Here is the fixed code which took me ages to find:

plugins {
    id "groovy"
    id "java"
    id "idea"
}

//Grade attributes
group 'com.nikecow'
version '0.1'

task wrapper(type: Wrapper) {
    gradleVersion = "3.0";
}

repositories {
    mavenCentral()
}

configurations {
    // configuration that holds jars to include in the jar
    extraLibs
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.7'
    extraLibs group: 'net.java.dev.jna', name: 'jna-platform', version: '4.2.2'
    testCompile group: 'junit', name: 'junit', version: '+'
    configurations.compile.extendsFrom(configurations.extraLibs)
}

jar {
    from {
            configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
        }
}

Now what you put behind “extraLibs” will be both compiled and included into your jar as a dependency. Hopefully it helps out some other people.


Publish artifact to maven with only a direct dependency bundeled in with transitive dependencyes defined in pom
(Filipe Esperandio) #6

This is very interesting, but in my case I can only compile the code if I add the lib to both compile and extraLibs, any idea?


(Carl Henrik Janson) #7

@David_Karr, your information makes sense. However, when everything runs fine during compilation (and run), but gradle cannot find dependencies during jar packaging (none of them found), then the process of building a jar file so as to make a library project available as a traditional jar library, becomes a timethief.

Timethieves should be avoided, if nothing else, then at the very least by teaspoon explanations in the Gradle tutorials. Here is an example on a tutorial that I would expect to find in a Gradle tutorial on how to migrate to Gradle: https://www.mkyong.com/gradle/gradle-create-a-jar-file-with-dependencies/

Honestly speaking, it should be commodity and “a click of a button” at the most, to create such a jar file. This is what people has done for ages in the Java world, it is automagically happening in any java Netbeans project.

Gradle for Android Studio is a very good system, but as it seems, the pure java part of Gradle is not yet ready for proffesional usage. Another commodity example is that the compilation of native files that works fine in the Gradle Android plugin, is unavailable in the Java plugin. (This is a major missing)

The reason we need a gradle project converted into a jar library, is that some of our projects are based on traditional netbeans build systems. That will change (to Gradle), but not with any priority.

I am using a Gradle plugin for Netbeans precisely for that purpose of migrating everything to Gradle, and it is working just fine in other respects.

Please comment.


(Tim) #8

Thank you so much for actually revisiting the question. Helped me much.


(Nikecow) #9

Perhaps because you use another Gradle version ? I am not sure though.

Btw, this thread has accumulated over 25.000 views, that’s amazing!


(Oleksii) #10

You are my hero - you saved my day!


(Jyoti Gurjar) #11

Hi Nikecow,

Your solution worked for me.
Thanks for posting the solution.


(Chris Jones) #12

Thanks so much! This was a big pain for me as I’m also a Gradle newbie. You solution made huge progress for me!