6

I have a gradle task to create a jar file containing Java source files to be included in an Android aar library package. These files will serve as Javadoc for JNI to a C++ library also bundled in the aar package.

I cannot possibly figure out how to include the jar file and not compile the files within. it seems that the Java files in the jar file are compiled, which does not help me - I just want to include them so that they are available to developers using that aar package.

The created jar file has all the sources and is in the output aar inside its libs directory, but it has no contents.

How can I add the Java sources to my aar?

Jar creation

The Jar is created as follows and ends up in the build/libs folder of my module.

task generateMySources(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}

artifacts {
    archives generateMySources
}

preBuild.dependsOn(":myModule:generateMySources")

dependencies {
    // The jar is included but it is empty inside the aar.
    compile files('build/libs/myModule-sources.jar')
}

The output jar contains:

.
├── com
│   └── my
│       └── app
│           └── jni
│               ├── File1.java
│               ├── File2.java
│               ├── File3.java
│               └── File4.java
└── META-INF
    └── MANIFEST.MF // Contains "Manifest-Version: 1.0" only.

The jar exists inside the aar inside the libs directory, but now it is empty.

3
  • Opening the corrupt jar with Notepad++ gives PK ENO ACK NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL NUL while Notepad gives PK . Doing less in a Linux shell gives PK^E^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@. So probably not very useful output. Commented Jan 11, 2017 at 8:58
  • What is the gradle code to create the .jar? Commented Jan 11, 2017 at 9:01
  • 1
    I added the Gradle code for Jar creation. The Jar archive becomes empty, not corrupt (I was doing something wrong). Commented Jan 11, 2017 at 9:35

2 Answers 2

7
+50

Only thing I could come up with is to add your sources to the .aar file after it's built like so

task generateMySources(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}
task addMySourcesToAar(type: Jar) {
    archiveName "myModuleWithSources.aar"
    destinationDir file("build")
    from zipTree("build/outputs/aar/myModule-release.aar")
    from fileTree("build").include("libs/myModule-sources.jar")
}
afterEvaluate { project ->
    project.tasks.preBuild.dependsOn generateMySources
    project.addMySourcesToAar.dependsOn build
}
artifacts {
    archives addMySourcesToAar.archivePath
}

and run

./gradlew myModule:addMySourcesToAar

I didn't add anything to dependencies like you did

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this definitively works. As for the part of my question: I want to use this jar as source code in Android Studio. Is this possible while having it inside the libs directory inside the aar? I realize now that this may not be the proper approach. Having the jar file externally and selecting that as source in Android Studio works, but it is only possible to select jar and zip files for sources, not aar files.
I don't know if you can use the jar as source code in Android Studio as you describe. I am not sure exactly what you're doing but if I were developing an aar I would expect some people to want the jar with classes if they just want to use the functionality in your library, and other people would want the source if they want to change it. I wouldn't think users would want BOTH. So I would distribute separate artifacts, one of the source and one of the aar.
I ended up distributing the jar with sources separately. It seems that this is what Android Studio expects. If I open the decompiled sources from the aar, it is possible to click Attach Sources in the top right corner and select the jar. It seems like this is the "correct" way of doing this, and I cannot find any documentation to include it in the aar anywhere.
5

For thus who are using Gradle Kotlin DSL:

tasks.register<Jar>(name = "sourceJar") {
    from(android.sourceSets["main"].java.srcDirs)
    classifier = "sources"
}

publishing {
    publications {
        create<MavenPublication>(name = "Maven") {
            run {
                groupId = "groupId"
                artifactId = "module-name"
                version = "1.0"
                artifact("$buildDir/outputs/aar/module-name-release.aar")
                artifact(tasks["sourceJar"])
            }
        }
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.