Parceler and Lombok not working together?

試著忘記壹切 提交于 2019-12-06 03:23:21

This gets into how Lombok adds code to your class. Lombok uses a known trick in the Java annotation processor to add code to your class. This added code is not visible to Parceler during the annotation processor round and makes the added no-args constructor unknown to Parceler.

I'd recommend adding the no-args constructor manually, annotating the existing constructor with @ParcelConstructor (I assume you have one) or consider using the Lombok fork Hrisey that has an @Parcelable annotation.

We had an issue/question about this recently: https://github.com/johncarl81/parceler/issues/177

EDIT: Initial solution failed after I did some cleaning, also, it didn't work with Proguard. See updated solution below.

To solve this problem, I had to create my own custom annotation processor. The idea of this processor was to ensure processor order for the processors used by Lombok and Parceler.

Here are the steps I followed to resolve this problem:

Step 1

Create a new Java Module under the root project. Call it any name, for example parceler-lombok, use any class name/package of your choice.

Step 2

Add lombok and Parceler annotation classes as dependency to the new module, and set source compatibility.

//File: parceler-lombok/build.gradle
apply plugin: 'java'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'org.projectlombok:lombok:1.16.16'
    compile 'org.parceler:parceler:1.1.9'
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

Step 3

Create the following directory in your main source folder for the module: src/main/resources/META-INF/services

Step 4

Create a file called javax.annotation.processing.Processor inside the directory above.

Step 5

Edit the file, and add the following lines.

lombok.launch.AnnotationProcessorHider$AnnotationProcessor
lombok.launch.AnnotationProcessorHider$ClaimingProcessor
org.parceler.ParcelAnnotationProcessor

This is a declaration of all the annotation processors available in your module. The order shows that Lombok annotation processors should be loaded before parceler's

Step 6

Now that we have our "custom annotation processor", go back to your main app module, in your build.gradle file for app, do the following:

  • Remove lombok dependency (annotatorProcessor, provided or compile) directive
  • Remove the parceler annotationProcessor dependency (i.e. org.parceler:parceler), leave the API dependency as-is.
  • Now add your custom annotation processor as a dependency
  • Finally, ensure Java 1.7 compatibility

See snippets below :

//File: app/build.gradle
android {
  //...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
  //...
}

dependencies {
    // ...
    //Remove these ones
    //provided 'org.projectlombok:lombok:1.16.16'
    //annotationProcessor 'org.parceler:parceler:1.1.9'

    //leave parceler API
    compile 'org.parceler:parceler-api:1.1.9'
    provided project(':parceler-lombok')
}

Using provided ensures that the annotation processor classes are not bundled with your app.


The following articles were very helpful:

Use @ParcelFactory on a static method building an empty object:

@Builder
public class MyClass {
    @ParcelFactory
    static MyClass fromParcel() {
        return builder().build();
    }
}

This trick can ben used with Jackson and other libraries allowing you to annotate static factory methods in addition to constructors.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!