Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle: how do I include a local jar from a dependent java project in an Android build?

In my Android app, I'm getting a java.lang.NoClassDefFoundError when the code that references code in a dependent .jar is executed. My project includes an Android module as well as a java-only library module, which is where the jar dependency is. I'm using gradle 1.10 to build the project. Here is my project layout:

myProject
- app (Android)
  - src
  - build.gradle

- lib (java)
  - src     
  - libs
    - local-dependency.jar
  - build.gradle

- build.gradle
- settings.gradle

The main project build.gradle is blank while the main project settings.gradle looks like:

include ':app', ':lib'

The Android app build.gradle looks like:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.8.+'
    }
}

apply plugin: 'android'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 18
    buildToolsVersion "19.0.2"

    defaultConfig {
        minSdkVersion 18
        targetSdkVersion 18
        versionCode 1
        versionName "1.0"
    }
}

dependencies {
    compile project(':lib')
}

The library build.gradle is:

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile <some-dependency-in-maven>
    compile files('libs/local-dependency.jar') 
}

Everything compiles and packages with no errors and I'm not seeing any errors in the IDE (IntelliJ 13). For some reason, my local-dependency.jar is not getting added to the dex-ing process during the Android compile. Any maven dependencies specified in the lib project get added to the Android .apk just fine; it's just my local jar dependency. Is there something I'm missing?

Thanks!

like image 829
gmusick Avatar asked Mar 12 '14 18:03

gmusick


2 Answers

In recent (4+, IIRC) versions of gradle, you can achieve this with the following configuration:

compile (project(':ProjectIDependOn')) {
  transitive = true
}

Setting transitive to true when depending on another project will expose all of that project's libraries to this project.

like image 91
Dmitri V Avatar answered Oct 14 '22 02:10

Dmitri V


This is not directly possible as local jars are not declared as transitive dependencies in Gradle.

You have two options:

  • merge the two jars in your java library so that the output contains the local jar.
  • create a different project with no source, only the jar, and make the project depend on it.

The second option gives you the ability to have more than one project depend directly on the local jar (on top of it becoming a transitive dependency). To do it, create a new gradle project and just put in its build.gradle the following:

configurations.create("default")
artifacts.add("default", file('somelib.jar'))

This simply register your jar as the default artifact published by the project and this will get consumed by the other projects.

like image 40
Xavier Ducrohet Avatar answered Oct 14 '22 04:10

Xavier Ducrohet