8

I'm building an Android app that has a dependency on a custom library, and Gradle is only willing to include my custom library when I use a project dependency, not when I use a files dependency to include the library's jar file. I'm building both my app and the library with the API levee 19 SDK.

failing dependencies section from build.gradle:

dependencies {
  compile 'com.android.support:appcompat-v7:+'
  compile files('libs/MyLibrary.jar')
}

If I use the above dependencies section, none of the class in MyLibrary.jar are included in the build apk file, as verified by extracting its classes.dex and running dexdump. I have also verified that all of the classes are present in the jar file I'm using.

If I use the following dependencies section, then all of the classes in MyLibrary are included in the apk file:

dependencies {
  compile 'com.android.support:appcompat-v7:+'
  compile project(':MyLibrary')
}

I'm using Android Studio 0.4.0, Gradle 1.9, and I think the Gradle plugin 0.7.1.

What is going on here? I'd really like to build my app with the API level 18 sdk to test compatibility, but I can't get that working unless I'm able to just use the jar file for my library.

Greg
  • 10,360
  • 6
  • 44
  • 67
  • 1
    Shouldn't you have a version instread of + ? compile 'com.android.support:appcompat-v7:19+' – Benoit Dec 23 '13 at 17:49
  • Are you trying to include the jar file itself in your APK or just the classes from the jar? – superEb Dec 23 '13 at 17:54
  • I am only trying to include the classes from the jar. – Greg Dec 23 '13 at 17:58
  • Although I would also be happy if the result was to include the jar and add it to the app's classpath. Anything to get around the ClassNotFoundException I'm getting when I try to use a class in the library. – Greg Dec 23 '13 at 17:59
  • @Greg Can you **compile** your project with the dependency set as `compile files('libs/MyLibrary.jar')`? – kukido Dec 26 '13 at 20:01
  • Yes, there are no problems compiling the project with the dependency set either way. It's just that the dependency's classes are not included in the final apk if I use the `files` dependency. – Greg Dec 27 '13 at 16:50
  • @Greg: Interesting. Can you post the whole build.gradle? – kukido Dec 27 '13 at 21:18
  • @Andrey I've edited the question to include the build.gradle. – Greg Dec 30 '13 at 16:28

3 Answers3

3

Okay, this was my fault. My library's build.gradle was configured to only include the source files in the jar output file. The following is incorrect Gradle code and will give you the same problems as I've had.

task jar(type: Jar) {
  from android.sourceSets.main.java
}

This answer shows how to fix the jar file creation. It's ugly, but it seems to work.

Community
  • 1
  • 1
Greg
  • 10,360
  • 6
  • 44
  • 67
1

Jar task does not include dependencies in the final jar artifact.

From Gradle documentation on jar task:

The jar task creates a JAR file containing the class files and resources of the project.

It assumes that since you are building jar for your project, all dependencies will be provided during runtime. As opposed to war, where all dependencies are usually included in the final artifact.

If you need to create "fat jar", which will include the dependencies, then look into specific plugins, for example gradle-fatjar-plugin.

kukido
  • 10,431
  • 1
  • 45
  • 52
  • I'm not creating a jar, I'm creating an Android app. The app is not including the classes from a jar I'm trying to build into it. – Greg Dec 26 '13 at 15:55
  • When you declare a dependency on some library, it does not mean that the dependency will be expanded and included in your final artifact, unless you explicitly say so. You can look into `build` directory of your project to see what goes where and try to run `gradle` with `--info` flag. – kukido Dec 26 '13 at 18:20
  • How do I control what *is* included in the final artifact then? All the other dependencies have all their classes included, and if I declare this dependency as a `project` dependency instead of a `files` dependency, then its classes are included. – Greg Dec 26 '13 at 19:25
  • Got it. Could you please set **absolute** path to `MyLibrary.jar` and see if it's included. – kukido Dec 26 '13 at 20:00
  • I'm not seeing any difference using an absolute path vs. a relative path. – Greg Dec 27 '13 at 16:50
  • Realized that my custom jar task is collecting the library's source files, not its class files. Also that the docs you referenced in your answer are for the `java` plugin and I'm using the `android-library` plugin which doesn't seem to have useful tasks defined. – Greg Dec 31 '13 at 19:44
0

It's a little bit of a longshot, but if you're not using Android Studio 0.4.0 and you've just added the jar file, try cleaning your project and rebuilding from scratch. We've seen this bug: https://code.google.com/p/android/issues/detail?id=63366 where libraries don't get included without cleaning the project, though this bug refers to a dependency downloaded from Maven and not a local jar file (which may or may not be an important difference). This was fixed in Android Studio 0.4.0 (more specifically, in the Gradle plugin 0.7.0).

Scott Barta
  • 79,344
  • 24
  • 180
  • 163
  • I'm already using Android Studio 0.4.0, and I think I'm using the Gradle plugin 0.7.1. How can I check which version of the Gradle plugin I'm using? I've also tried cleaning and rebuilding after each change I've made. – Greg Dec 23 '13 at 18:27
  • If you're using android studio 0.4.0 then you're using at least 0.7.0 of the plugin and shouldn't be hitting this particular bug. So it's something else though I don't exactly know what. – Scott Barta Dec 23 '13 at 19:21
  • I just tried to create a simple test case and wasn't able to reproduce your problem. I'm starting to wonder if there's some issue with how the Android plugin links together APKs from multiple dexed sourc.es (based on other problem reports of a similar nature I've seen), but if there's a problem, it's not a trivial one to find – Scott Barta Dec 28 '13 at 22:22
  • As far as I can tell, there is only one dexed source. The dependency should be just a plain old .jar file, not dexed. I do suspect a bug somewhere in the build system at this point, but I don't understand the system well enough to pick it out. – Greg Dec 30 '13 at 15:14
  • Figured out what the problem was with trying to include the jar file: the jar only had the source files for the library. Replaced question with one expressing the new problem: how do I create a jar file with the classes for my library. – Greg Dec 31 '13 at 19:57
  • I'd encourage you to roll back the edit to your question and post the new problem as a separate question. Otherwise the answers your already accumulated will be confusing to other readers. – Scott Barta Dec 31 '13 at 20:50