39

I'm trying to build an Android project that has some dependencies. The jar files are in the lib/ directory. I can build the project by adding those jar file to my classpath, but of course it Force Closes in the emulator because those libraries aren't present.

I'm doing this from the command line with ant (not in eclipse). How can I make it include those libraries in the apk from the command line?

Jay K
  • 2,081
  • 1
  • 17
  • 19

9 Answers9

29

Jay K's answer was right at the time of writing, but now the SDK has changed, and here is the new way to do it:

Add the following line to ant.properties:

jar.libs.dir=lib

Tested, works where external.libs.dir does not work.
That changed in December 2010 and then again in October 2011.

Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373
  • 6
    how do i declare multiple directories? What is the separater? – Taranfx Nov 02 '11 at 16:55
  • 1
    There isn't one. It's "jar.libs.dir" not "jar.libs.dirs". You may only specify a single directory. But in that directory you may link to as many jars as you need. – Scott C Wilson Mar 30 '12 at 00:46
12

Just for future reference: Right now there is a bug in the SDK which prevents of using jar.libs.dir: http://code.google.com/p/android/issues/detail?id=33194

A simple solution to use jar.libs.dir again (while waiting for the bug to get fixed), is to add this target in the build.xml file:

<target name="-pre-compile">
    <path id="project.all.jars.path">
        <path path="${toString:project.all.jars.path}"/>
        <fileset dir="${jar.libs.dir}">
            <include name="*.jar"/>
        </fileset>
    </path>
</target>
Panayotis
  • 1,792
  • 23
  • 32
  • you cannot overwrite the project.all.jars.path like you have in your example. It will result in a null pointer exception during the ant build process because you are re-defining project.all.jars.path so that ${toString:project.all.jars.path} will evaluate to null. The correct way to do this is to introduce a temp.jars.path into which you include you new jars dir, and then you overwrite the project.all.jars.path with temp.jars.path – Akos Cz May 24 '13 at 19:01
8

At compiling do this:

javac -encoding ascii -target 1.5 -d bin/classes \
-bootclasspath $SDKDIR/android.jar src/some/project/* -classpath=libs/*.jar

And, when you are generating the bytecode for Dalvik:

dx --dex --output=bin/classes.dex bin/classes libs/*.jar

Also, when you are packaging the APK file:

apkbuilder bin/something.apk -z bin/projectname.ap_ \
-f bin/classes.dex -rf src -rj libs

I'm assuming you are using Linux... on Windows will be almost the same.

Cristian
  • 198,401
  • 62
  • 356
  • 264
7

Answering my own question:

I created a file "build.properties" and added the line

external.libs.dir=lib

It was a lucky guess, really.

Jay K
  • 2,081
  • 1
  • 17
  • 19
  • When I do this, ant creates a "libs" directory. If I put the jars inside, it works. Unfortunately I need to use "lib", because everyone has configured "lib" in Eclipse. And this solution does not work for me :-/ – Nicolas Raoul Feb 15 '11 at 08:08
  • But, if I need add two libraries from separated folders? What I need do? – RagnarR Feb 03 '12 at 10:04
6

The example above dosen't quite work right. You cannot overwrite the project.all.jars.path inline. Following is a working example :

<target name="-pre-compile">
<!-- HACK to add the android-support-v4.jar to the classpath directly from the SDK -->

    <echo>ORIGINAL jars.path : ${toString:project.all.jars.path}</echo>
    <path id="project.all.jars.path.hacked">
            <path path="${toString:project.all.jars.path}"/>
            <path path="${sdk.dir}/extras/android/support/v4/android-support-v4.jar"/>
    </path>

    <path id="project.all.jars.path">
            <path path="${toString:project.all.jars.path.hacked}"/>
    </path>
    <echo>HACKED jars.path : ${toString:project.all.jars.path}</echo>

</target>
Akos Cz
  • 12,711
  • 1
  • 37
  • 32
3

If you store your libraries in ${basedir}/libs the ant script will be able to find them.

I looked at the current ant script ( ${sdk.dir}/tools/ant/build.xml ) and it defines jar.libs.dir to "libs".

FYI, the ant script is well documentated so it's easily to trace through.

If you move libs around be sure to edit your .classpath files to prevent eclipse users from suffering needlessly.

Peter Kahn
  • 12,364
  • 20
  • 77
  • 135
1
external.libs.dir=lib

after 2 hours of searching for this answer, this worked for me. The jar file in my libs directory finally compiles AND is bundled with the APK.

sra
  • 23,820
  • 7
  • 55
  • 89
gpacer68
  • 11
  • 1
1

put jars in ${YOUR_PROJECT}/libs directory

shaobin0604
  • 1,179
  • 12
  • 14
0

The jar.libs.dir property is a single directory. It's not like a CLASSPATH which is a colon/semicolon separated list. The way to have multiple directories in your jar.libs.dir is to not set it directly; let it default to libs and go to libs and create the required soft links to .jar files you need.

Scott C Wilson
  • 19,102
  • 10
  • 61
  • 83