75

I have to create a library that I am going to export to the client in a jar file. Is there any way to create a jar with the resources in it?

The Google adMob have such a jar, which includes resource file such as R$layout.class in it. This page describes some way to do that but I am not able to understand exactly how am I supposed to import the library project to an application using the method above.

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
Aayush Rana
  • 1,303
  • 1
  • 12
  • 19

8 Answers8

81

This is the closest that you can get:

Step #1: Create a regular Android library project, and get it working.

Step #2: Copy that Android library project into another directory.

Step #3: Create a JAR from the compiled Java classes from the original Android library project, and put that JAR in the libs/ directory of the copy you made in Step #2. You should be able to run ProGuard on this JAR manually, though I haven't tried that.

Step #4: Remove everything inside the src/ directory of the copied library project, leaving behind and empty src/ directory.

Step #5: ZIP up or otherwise distribute the copied Android library project.

This will give you an Android library project like the Play Services one, where the resources are available, but the source code is not.

UPDATE: An even better approach nowadays is to package your library project as an AAR, which is Android's native way of creating a reusable artifact from your compiled code plus required resources. At the present time (July 2014), Gradle for Android, Android Studio, and the android-maven-plugin can create and consume AARs.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 5
    A library project differs from a standard Android application project in that **you cannot compile it directly to its own .apk and run it on an Android device**. Similarly, you cannot export the library project to a self-contained JAR file, as you would do for a true library. Instead, you must compile the library indirectly, by referencing the library in the dependent application and building that application. this quote from doc supports your answer i guess – Raghunandan Jun 12 '13 at 11:16
  • @CommonsWare Your outline works very well if ProGuard is **not** run on the JAR. If you do apply ProGuard (manually) to the JAR, then all dependent projects will complain about all referenced symbols "cannot be resolved". I just tried it and that's what I received. Am I missing something? – stumpped Jul 31 '13 at 00:29
  • 1
    @stumpped: You need to have your ProGuard configuration file set up to not obfuscate the names of public stuff that the dependent projects need. – CommonsWare Jul 31 '13 at 00:38
  • @CommonsWare quoting the official guide: **Note: You need SDK Tools r14 or newer to use the new library project feature that generates each library project into its own JAR file.** http://developer.android.com/tools/projects/index.html#LibraryProjects – Mahmoud Abou-Eita Dec 28 '13 at 22:55
  • yet on the same page: **You cannot export a library project to a JAR file A library cannot be distributed as a binary file (such as a JAR file). This will be added in a future version of the SDK Tools.** – Mahmoud Abou-Eita Dec 29 '13 at 12:00
  • @MahmoudAbou-Eita: Efforts are now focused on AAR artifacts, from the new Gradle-based build system. – CommonsWare Dec 30 '13 at 21:39
  • @CommonsWare Using this approach, which resources should I exclude from the eclipse JAR export wizard. Including everything causes build problems. (Duplicate Drawables and Manifest) – Mahmoud Abou-Eita Jan 01 '14 at 10:07
  • @MahmoudAbou-Eita: I never use the Eclipse JAR export wizard, and this has nothing to do with creating an AAR artiface anyway. – CommonsWare Jan 01 '14 at 12:53
  • @CommonsWare I was referring to the sourceless library project approach mentioned in the main answer. My issue is solved anyway. Thanks. – Mahmoud Abou-Eita Jan 01 '14 at 13:18
  • A little late to the party now that we have AARs but if you still build with ant like me this will do steps 1-3 for you. http://stackoverflow.com/a/24580308/384306 – Nathan Schwermann Jul 04 '14 at 20:14
  • @schwiz, If AAR works, why does the page http://developer.android.com/tools/projects/index.html#LibraryProjects state "**you must compile the library indirectly**, by referencing the library in the dependent application and building that application"? – Pacerier Nov 14 '14 at 05:13
  • @Pacerier: That documentation is for a regular Android library project, not one packaged as an AAR. AAR is only supported by Android Studio (and Gradle for Android), and little documentation on that has been merged into http://developer.android.com at this time. – CommonsWare Nov 14 '14 at 12:08
  • Now i am using gradle and i have to privde to customer jar with resources. I made jar and put resources to res folder. But project that uses this library throws exception like ResourceNotFound with id. What is a problem? Please don't say about module and arr. I have to privide jar – Vetalll Nov 28 '14 at 14:57
  • @Vetalll: "i have to privde to customer jar with resources" -- there really isn't such a concept. You are welcome to attempt to create a binary-only Android library project, but I don't have any current recipes for that. Or, you are welcome to unpack an actual AAR to effectively "reverse engineer" a binary-only Android library project: http://commonsware.com/blog/2014/07/03/consuming-aars-eclipse.html – CommonsWare Nov 28 '14 at 16:47
  • I have been searching for this solution for so long. Tried so many things and here is the best and fasted of them all. Is there any way i can vote this answer up, a 100 times??? – Muneeb Mirza Dec 01 '14 at 12:27
  • How to Create a JAR file from the compiled Java classes from the original Android library project can you please help suggesting what this statement mean. – user2273146 Dec 30 '14 at 10:45
  • i am getting Unable to execute dex: Multiple dex files define .../Manifest$permission; How to generate jar file without these manifest classes – png May 21 '15 at 13:55
  • can we merge external libraries like `retrofit` , `realm` etc into our custom library project and distribute – Hunt Mar 17 '16 at 08:13
22

This works!

  1. Make your library project a normal project by deselecting IsLibrary flag.
  2. Execute your project as Android Application. (It will not show any error)
  3. You'll find a .jar file in bin folder along with .apk.
  4. Give you .jar who want to use your library.
  5. Tell them to just import external jar into build path.

This will work fine with all the resources. Thanking you all. for your responce

Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
Aayush Rana
  • 1,303
  • 1
  • 12
  • 19
  • When I do this, I do not get a .jar file generated in my bin/ directory? – David Doria Sep 09 '13 at 15:27
  • I only get the .jar when I DO have "Is Library" checked. However when I add that to my dependent project, the resources don't work. – David Doria Sep 09 '13 at 15:41
  • 2
    if you want resources to work check this: http://stackoverflow.com/a/17064024/1779907. The method I explained in answer works if you have an library that do not have any resources. If you want to secure you resources too please hard code them in java (like I used base64 encoding to save my Images directly within a java interface) and then u can use the method explained in my answer(work better if u have less resources). – Aayush Rana Sep 10 '13 at 06:23
  • See my answer [here](http://stackoverflow.com/a/18594605/281545) for an easier way - btw your answer put me to the right track ;) – Mr_and_Mrs_D Sep 27 '13 at 19:56
  • 5
    This would not work with resources! that jar, doesn't even have the res library in it, you've probably overlooked the properties of the project using the library!. – TacB0sS Dec 24 '13 at 10:13
14

Follow the below steps to obtain a distributable jar of your library (verified for library project without external dependencies):

  1. Create your library project. Clean it. You will get a libraryProjectName.jar file inside the bin folder. (Make sure "is Library" is selected in the library project.
  2. Copy the .jar file into the libs folder of your target application
  3. Refresh your workspace and press Ctr+Shift+O (on Windwows/Linux) or Cmd+Shift+O (on Mac) to resolve any import dependencies from the library added.

Comment in case facing any issue.

Akshat Singhal
  • 1,801
  • 19
  • 20
  • 6
    This is by far the simplest way to create a JAR from a Library Project but... it doesn't contain the `res` and the `assets` folders. Am I missing something? – ripopenid Dec 06 '13 at 00:45
  • @ripopenid Those cannot be in a JAR. That's what you need to reference library projects for. – caw Nov 08 '14 at 14:40
  • @MarcoW., Only `res` is possible, Even referencing doesn't allow us to use `assets`, See http://developer.android.com/tools/projects/index.html#LibraryProjects : "Any asset resources used by an application must be stored in the assets/ directory of the application project itself". – Pacerier Nov 14 '14 at 05:17
  • That's right. A JAR gets you the `src` directory. A library project gets you `res` in addition. More is not possible. – caw Nov 14 '14 at 05:21
3

You cannot package resource files into jar. You can export your project as a library project.

You export your utility classes that do not refer to resources in android ie pure java classes as jar file.

Check the link below

http://developer.android.com/tools/projects/index.html

To make your project a library project

Right click on your project. Go to properties. Choose Android. Make sure Is Library is checked.

To refer the library project in your android project

Right click on your project. Go to properties. Choose Android. Click Add. Browse and the library project.

Quoting from the docs

A library project differs from a standard Android application project in that you cannot compile it directly to its own .apk and run it on an Android device. Similarly, you cannot export the library project to a self-contained JAR file, as you would do for a true library. Instead, you must compile the library indirectly, by referencing the library in the dependent application and building that application.

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • 1
    A library cannot be distributed as a binary file (such as a JAR file). This will be added in a future version of the SDK Tools. Quoting from http://developer.android.com/tools/projects/index.html – Raghunandan Jun 12 '13 at 11:11
  • 8
    Int he new [Gradle build system](http://tools.android.com/tech-docs/new-build-system/user-guide), you will have the possibilities to create a so called aar-file (Android Archive), that is exactly what you want. Its basically like an APK (containing resources, manifest, etc.) just for libraries. So switch to Gradle, if you want proper support for that. – Tim Roes Jun 12 '13 at 11:19
  • I didn't downvote (not enough points) but I can guess that instead of answering **How** to create jar for Android Library Project, you answered that it is not possible. All other answers actually show a (working) way to create such jar. – ripopenid Dec 06 '13 at 01:11
3

Tested with adt 22.2.1

  1. Create your library project
  2. Create empty project
  3. Add library project to your empty project
  4. Build project
  5. In /gen folder you will find class for your library project, this will contain your resources for lib project.
  6. Export JAR (select only this class ... from /gen folder)
  7. Export JAR from your lib project
  8. Rename exported files to zip and merge content
  9. Rename the final file as JAR and add it to project.
Eenvincible
  • 5,641
  • 2
  • 27
  • 46
coltbg
  • 33
  • 1
  • 2
  • Did you try applying Proguard to the JAR? If so, how did it work? Were there any difficulties or complications? – ripopenid Dec 04 '13 at 03:30
  • Step #6 would have made your approach a better newer alternative to @CommonsWare's approach, except that it doesn't really work if the user (i.e. application project) of this library, defines its own resources. So looks like CommonsWare's method is still the best. – ripopenid Dec 06 '13 at 01:47
  • This will not include the resources, which is usually the point behind an Android library project. – CommonsWare Jul 04 '14 at 19:24
1

Here is an easy way to do it with ant, found this in the Volley sourcecode. Add the code below to custom_rules.xml then build with ant jar

<?xml version="1.0" encoding="UTF-8"?>
<project name="volley-rules" default="help">

  <!-- A rule to generate the JAR for inclusion in an Android
       application. Output file will be bin/volley.jar -->
  <target name="jar" depends="-compile">
    <jar destfile="bin/volley.jar"
         basedir="bin/classes" />
  </target>
</project>
Nathan Schwermann
  • 31,285
  • 16
  • 80
  • 91
1

As per latest Android Studio v1.2, its as easy as having a cake. Already answered complete solution with screenshots on this link

Community
  • 1
  • 1
Nishant Srivastava
  • 4,723
  • 2
  • 24
  • 35
0

With Eclipse ADT v22.6.2 you can just export jar by clicking File->Export->Java->Jar File, select directories and destination where to save.

someUser
  • 965
  • 12
  • 24