Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Annotation Processors generated resources not packaged to APK

I've custom annotation processor generating factory classes and META-INF/services/factory.interface.class resource.

Annotation processor is used in library project and all generated files are packaged correctly into AAR.

When I use annotation processor in application project with library added as a dependency only classes from libraries META-INF/services/factory.interface.class exist in APK/META-INF/services/factory.interface.class

After some investigation I realized that MergeJavaResourcesTransform in android-gradle-plugin-1.5.0 (and 2.0.0-alpha3) looks for resources for merging in all exploded-aars, jars, and intermediates/sourceFolderJavaResources

Is there any way to merge META-INF from intermediates/classes (it's where resource files from annotation processor get created) or make annotation processor create file in sourceFolderJavaResources?

Only workaround I've found so far is to add CopyTask in application's buildscript

android.applicationVariants.all { variant ->
  def variantName = variant.name
  def variantNameCapitalized = variantName.capitalize()
  def copyMetaInf = tasks.create "copyMetaInf$variantNameCapitalized", Copy
  copyMetaInf.from project.fileTree(javaCompile.destinationDir)
  copyMetaInf.include "META-INF/**"
  copyMetaInf.into "build/intermediates/sourceFolderJavaResources/$variantName"
  tasks.findByName("transformResourcesWithMergeJavaResFor$variantNameCapitalized").dependsOn copyMetaInf
}

But I do not wat to force compiler an library users do do anything more than adding dependencies.

like image 955
skyman Avatar asked Dec 16 '15 07:12

skyman


People also ask

What is an annotation processor?

Annotation processing is a powerful tool for generating code for Android apps. In this tutorial, you'll create one that generates RecyclerView adapters.

How does annotation processing work?

Annotation Processing APIEach annotation processor, in turn, is called on the corresponding sources. If any files are generated during this process, another round is started with the generated files as its input. This process continues until no new files are generated during the processing stage.

How do I run an annotation processor?

Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors -> Enable Annotation Processing.

What are Android annotations?

Annotations allow you to provide hints to code inspections tools like Lint, to help detect these more subtle code problems. They are added as metadata tags that you attach to variables, parameters, and return values to inspect method return values, passed parameters, local variables, and fields.


1 Answers

It seems that the issue is related to META-INF folder. Here is the bug reported for Service Loader and META-INF

By the way, there is a confirmed solution:

  • right click on /src/main (where you have /java and /res folders),
  • select New > Folder > Java Resources Folder,
  • click Finish (do not change Folder Location),
  • right click on new /resources folder,
  • select New > Directory
  • enter "META-INF" (without quotes),
  • right click on /resources/META-INF folder,
  • select New > Directory
  • enter "services" (without quotes)
  • copy any file you need into /resources/META-INF/services

Also, you may want to check the following questions on SO:

  • META-INF/services in JAR with Gradle
  • Using serviceloader on android

Initial Answer:

You might want to try to configure your library source set's resources attribute (with your location of META-INF/services) which is responsible for:

The Java resources which are to be copied into the javaResources output directory.

Here is an example:

android {
    ...
    sourceSets {
        main {
            resources.srcDirs = ['/src/META_INF_generated']
        }
    }
    ...
}
like image 61
GregoryK Avatar answered Oct 12 '22 04:10

GregoryK