RegisterAdapter in multi-module projects is not working across modules
Closed this issue · 6 comments
See discussion in #116.
PaperParcel only knows about types that have been registered within the same module. Is there a way to get this to work across modules without having to duplicate type adapters?
Hi,
any progress here?
Unfortunately not. APT doesn't look at the annotations in any of your dependencies. Even if I include the annotation in the library binary (using a stronger retention), it doesn't make a difference, APT still won't find it.
I still have to figure out how this can be handled in a nice (alternate) way. Open to suggestions!
For now you'll have to define the adapter twice, or extend your library adapter in your main project and annotate it again so APT can pick it up. =/
I am using a library called TikXml for parsing XML Feeds. Here it is possible to use it across multiple modules. Maybe you can do it the same way:
- XML models are defined in a separate module, e.g.
@Xml class Video {
@Attribute lateinit var date: LocalDateTime
}
- In the app module i have to register a type adapter for (de)serializing the LocalDateTime field like this:
TikXml.Builder().addTypeConverter(LocalDateTime.class,LocalDateTimeConverter())
- The generated type adapter looks like this
try {
value.date = config.getTypeConverter(org.threeten.bp.LocalDateTime.class).read(reader.nextAttributeValue());
} catch(TypeConverterNotFoundException e) {
throw e;
} catch(Exception e) {
throw new IOException(e);
}
}
So your generated code should search a type adapter for an unknown class. You should a PaperParcelBuilder class to add type adapters manually in code.
What do you think about this suggestion?
I considered something like this, but this has some downsides to it:
a) you can only work with class files at runtime, and all generic information is lost. Currently PaperParcel adapters can work for generic constraints (e.g. intersection types).
b) loss of compile time validation. Now if a type can't be handled, you'll only know it at runtime when your app blows up. This is dangerous with a parcelable library as it's easy to run an app without ever triggering the parcelable code and then accidentally shipping to prod with a major defect.
@Bodo1981 I'm looking at making a global annotation for configuration of PaperParcel (within a module):
@ProcessorConfig(
adapters = {
@Adapter(DateAdapter.class),
@Adapter(value = SomeOtherAdapter.class, nullSafe = true, priority = HIGH)
},
excludeAnnotations = Exclude.class,
...
)
It's a combination of @RegisterAdapter
and @PaperParcel.Options
, but it'll work globally in a module. That way, you can define one of these @ProcessorConfig
things per java/kotlin module. This will fix this issue as you can include adapters from other modules.
This annotation should be able to be applied to any class, annotation, package, or interface within a module and the processor will pick it up (and there'll be a maximum of 1 per module).
In addition, I'll deprecate @RegisterAdapter
and @PaperParcel.Options
in favour of this approach.
Thoughts on this? Does it look OK to you?
Going to release beta2 and give the new API a try. Would still love feedback if you have any before the final release 😄