rharter / auto-value-moshi Goto Github PK
View Code? Open in Web Editor NEWAutoValue: Moshi Extension
License: Apache License 2.0
AutoValue: Moshi Extension
License: Apache License 2.0
When using auto-value-moshi with Kotlin, it seems like kapt is not generating any sources related to Moshi. The basic AutoValue classes are being generated, just nothing related to Moshi.
Is this a known issue? Let me know if I can provide more details.
auto-value-moshi:0.4.0-rc2
After discussion with the Moshi creators, we should utilize the built in default value support via the builder. There is a bit of complexity here, though, since you could have multiple static factory methods for builders, so I propose the introduction of @JsonDefault
annotation that can be added to a single, possibly protected, static factory method returning @AutoValue.Builder
to denote which one to use. This makes the logic for generated construction as follows:
@JsonDefault
annotated static factory method returning an @AutoValue.Builder
, use it.@AutoValue.Builder
, use it.I recently watched a talk by @JakeWharton about optimizing your code to not call getters multiple times when not necessary.
So it would be great to see that in the generated code so code like
if (value.name() != null) {
writer.name("name");
nameAdapter.toJson(writer, value.name());
}
will be simply
String name = value.name();
if (name != null) {
writer.name("name");
nameAdapter.toJson(writer, name);
}
Unfortunately we have a backend which is very restrictive. We are only allowed to send certain fields. Also there are fields which the server sends us but we're not allowed to send them back. On top of that we can't request a backend change.
API proposal:
@AutoValue
public abstract class MyAutoValue {
@Json(name = "name") String name(); // Can be sent & received
@Json(name = "foo") @SendOnly String foo(); // Will be used for serializing but not for deserializing
@Json(name = "bar") @ReceiveOnly String bar(); // Will be used for deserializing but not for serializing
}
The annotations need to be defined from the consumers and the processor will just check for name equality. (Same way auto-value-redacted works)
If you're open for this, I'm more than happy to send a PR for this.
Why? -> code style consistency & helps avoid elementary mistakes (un-used imports and so on).
Which? -> the current code style in the project is similar to the one used in moshi, so I would suggest that one and also enforcing usage of a common code style. May the the one from square?
What are your thoughts?
Hi, while migrating from auto-value-gson to auto-value-moshi, I've realized the latter doesn't play well with MoshiRequestBodyConverter
.
I've a simple AutoValue class which has the typeAdapter(Moshi)
method exposed - I can confirm that its fromJson is getting called while response is being deserialized, but the toJson is not called during serialization.
That is, Moshi's ClassJsonAdapter
is being picked up instead of the generated TypeAdapter from the switch-case in AutoValueMoshi_AutoValueMoshiTypeAdapterFactory
. I'm guessing this is because I'm passing in a AutoValue_Foo
class in my body and the switch-case returns null instead of returning TypeAdapter<Foo>
.
I found a relevant commit which was reverted: 57e0d1d
If I have a list like so:
List<? extends Thing>
The generated code fails to compile because it looks like this:
moshi.adapter(Types.newParameterizedType(List.class, ? extends Thing.class));
Using android-apt:1.4
with auto-value:1.2-rc1
+ auto-value-moshi:0.2.2
in my project.
Adapter sources are successfully generated but could not found AutoValueMoshiAdapterFactrory
as described in project document.
Error:(13, 17) error: Extension com.ryanharter.auto.value.parcel.AutoValueParcelExtension wants to consume a property that does not exist: writeToParcel
Above error occurs when I used both @autovalue and @MoshiAdapterFactory in single class that also implements parcelable and JsonAdapter.Factory.
Kindly help me.
I'm trying to use Retrofit 2, AutoValue, Moshi and the AutoValue: Moshi Extension in combination and I've run into the Cannot serialize abstract class issue.
I've created a POJO myself (Movie2) and a unit test which passes without problem for converting JSON to an instance of my POJO.
I have another unit test to verify that my JSON is converted to an instance of my POJO (Movie) created using AutoValue. Unfortunately this test always fails with the following stack trace:
java.lang.IllegalArgumentException: Cannot serialize abstract class com.appassembla.android.popularmovies.data.Movie
at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:59)
at com.squareup.moshi.Moshi.adapter(Moshi.java:94)
at com.squareup.moshi.Moshi.adapter(Moshi.java:61)
I've created a Gist with some sample code here. It includes my tests and the dependencies in my app's build.gradle. Let me know if you need anything else.
Hi, first of all thank you for this library.
I added android-apt and apt 'com.ryanharter.auto.value:auto-value-moshi:0.2-SNAPSHOT' to my gradle build file. If i sync gradle i get the following message:
Error:Could not find com.ryanharter.auto.value:auto-value-moshi:0.2-SNAPSHOT.
Searched in the following locations:
file:/D:/android/studio/gradle/m2repository/com/ryanharter/auto/value/auto-value-moshi/0.2-SNAPSHOT/maven-metadata.xml
file:/D:/android/studio/gradle/m2repository/com/ryanharter/auto/value/auto-value-moshi/0.2-SNAPSHOT/auto-value-moshi-0.2-SNAPSHOT.pom
file:/D:/android/studio/gradle/m2repository/com/ryanharter/auto/value/auto-value-moshi/0.2-SNAPSHOT/auto-value-moshi-0.2-SNAPSHOT.jar
https://jcenter.bintray.com/com/ryanharter/auto/value/auto-value-moshi/0.2-SNAPSHOT/maven-metadata.xml
.....
I tried other apt libs and have no error messages. Can you help me.
Thank you
With AutoValue 1.6, the annotations are no longer part of the AutoValue processor and are in a separate dependency, auto-value-annotations
. This processor assumes that these types will be present and so when updating to 1.6, a NoClassDefFoundException is thrown.
Caused by: java.lang.NoClassDefFoundError: com/google/auto/value/AutoValue
at com.ryanharter.auto.value.moshi.AutoValueMoshiAdapterFactoryProcessor.getSupportedAnnotationTypes(AutoValueMoshiAdapterFactoryProcessor.java:61)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:505)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:597)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:690)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
... 58 more
Caused by: java.lang.ClassNotFoundException: com.google.auto.value.AutoValue
... 68 more
The processor should either declare a dependency on auto-value-annotations
or migrate away from referencing the @AutoValue
by class and instead look it up via FQCN or Types
/Elements
.
I have a domain model with deep generics:
public abstract class Model {
public abstract ImmutableList<A<B<C<Long>>>> field();
The code that gets generated has a bug:
final class AutoValue_Model extends $AutoValue_Model {
public static final class MoshiJsonAdapter extends JsonAdapter<Model> {
private final JsonAdapter<ImmutableList<A<B<C<Long>>>>> fieldAdapter;
public MoshiJsonAdapter(Moshi moshi) {
Actual: this.fieldAdapter = moshi.adapter(Types.newParameterizedType(ImmutableList.class, Types.newParameterizedType(A.class, Types.newParameterizedType(B.class, Types.newParameterizedType(C.class, Long.class)))));
Needed: this.fieldAdapter = moshi.adapter(Types.newParameterizedType(ImmutableList.class, Types.newParameterizedTypeWithOwner(ImmutableList.class, A.class, Types.newParameterizedType(B.class, Types.newParameterizedTypeWithOwner(B.class, C.class, Long.class)))));
When I run the code that actually gets generated by 0.4.4
, I get:
java.lang.IllegalArgumentException: unexpected owner type for class com.mycompany.C: null
at com.squareup.moshi.Types$ParameterizedTypeImpl.<init>(Types.java:509)
at com.squareup.moshi.Types.newParameterizedType(Types.java:75)
at com.mycompany.AutoValue_Model$MoshiJsonAdapter
I figured out "Needed" by fixing one error at a time. The strange thing is that A
and C
needed to be created with Types.newParameterizedTypeWithOwner(
, but it was okay to create B
with just Types.newParameterizedType
.
I dunno why ๐คทโโ๏ธ. It's probably ill-advised to have generics this deep, I'm going to fix by reducing the nesting, but figured it was worth a bug report in case other people have this error.
I'm facing an issue where the server is refusing to accept request bodies if they contain any extra data. Is it possible to omit fields from getting serialized using auto-value-moshi
?
Will it be possible to read annotations on property methods and include annotations for constructor parameters? auto-value-moshi currently strips all annotations rendering IDE inspections unusable on them. The constructors generated by auto-value on the other hand include them as expected.
Hi @rharter, thanks a lot for your amazing library.
I'd like to report an issue I'm facing right now, which is I cannot have a field (or a method named) reader
.
This is due to https://github.com/rharter/auto-value-moshi/blob/master/src/main/java/com/ryanharter/auto/value/moshi/AutoValueMoshiExtension.java#L338
I'm guessing generated variable's name can be possibly modified not to let this kind of naming conflict happen, but what do you think about it?
All modules generate 'com.ryanharter.auto.value.moshi.AutoValueMoshiAdapterFactory' individually, so when modules refer to each other, one module can only refer its own 'AutoValueMoshiAdapterFactory' and lost part of 'JsonAdapter'.
Since https://github.com/rharter/auto-value-moshi/pull/76/files#diff-e17f3c4ec8512f83b9f9ec35523a3803L413 is not honoring @nullable properties when the actual JSON field is null
, if the field is just missing, everything works fine.
Take this example:
@AutoValue
public abstract class WithNullableClass {
public abstract String value();
@Nullable public abstract NullableClass nullableClass();
@AutoValue
public static abstract class NullableClass {
@Nullable public abstract String string();
}
}
This will fail with {"value":"value","nullableClass":null}
but not with {"value":"value"}
I have an @AutoValue
class Color
that de/serializes beautifully thanks to this extension.
However, I need to de/serialize List<Color>
. Does this extension support this use case?
If a class that uses the generated typeAdapterFactory
ends up having a null
value in the JSON, parsing fails with:
com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was NULL at path $.data
at com.squareup.moshi.JsonReader.beginObject(JsonReader.java:383)
at io.github.ktchernov.moshiautovaluebug.AutoValue_TestClassA_TestClassB$AutoValue_TestClassBJsonAdapter.fromJson(AutoValue_TestClassA_TestClassB.java:39)
at io.github.ktchernov.moshiautovaluebug.AutoValue_TestClassA_TestClassB$AutoValue_TestClassBJsonAdapter.fromJson(AutoValue_TestClassA_TestClassB.java:32)
at com.squareup.moshi.ClassJsonAdapter$FieldBinding.read(ClassJsonAdapter.java:183)
at com.squareup.moshi.ClassJsonAdapter.fromJson(ClassJsonAdapter.java:144)
at com.squareup.moshi.JsonAdapter$1.fromJson(JsonAdapter.java:68)
at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:33)
at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:37)
at io.github.ktchernov.moshiautovaluebug.MoshiAutoValueTest.parseWithNull(MoshiAutoValueTest.java:33)
....
What should happen, is that null
should be parsed as a null
object.
I've created a gist with a sample class and a unit test here: https://gist.github.com/ktchernov/cd3520cebf8aa56214b5155a648d38d4
The first unit test parseValid()
passes as expected, the second test parseWithNull()
fails with the above exception.
Given this class:
@AutoValue
public abstract class Foo<T> {
@MyJsonQualifier
public abstract T bar();
public static <T> JsonAdapter<Foo<T>> jsonAdapter(Moshi moshi, Type[] types) {
return new AutoValue_Foo.MoshiJsonAdapter(moshi, types);
}
}
The presence ofbar()
's JsonQualifier triggers the generation of another method:
private JsonAdapter adapter(Moshi moshi, String methodName) {
// ...
Method method = Foo<T>.class.getDeclaredMethod(methodName);
// ...
}
This in turn produces this error:
/path/to/generated/source/AutoValue_Foo.java:59: error: <identifier> expected
Method method = Foo<T>.class.getDeclaredMethod(methodName);
^
As far as I can tell, this error originates from here. Full source/generated code is available in this gist.
Is there something I'm missing or is this a genuine bug?
Not sure how this would work, but it would alleviate a ton of feature requests for features that this library probably shouldn't have to worry about by deferring to the moshi instance. Similar to how retrofit passes on annotations as well. This should make something like @serj-lotutovici's lazy adapters work with av models
@rharter thoughts? Might not be trivial, but I think it'd be a worthwhile endeavor
Hi,
After upgrading from 0.4.2 to 0.4.3 I'm getting
com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was NULL at path...
for null
value of @Nullable
field in @AutoValue
class.
I checked generated adapters for both versions and relevant code looks OK... in toJson()
method there are checks for null so annotation seems fine...
Note: I am using @MoshiAdapterFactory
Am I missing something and this is desired behavior,
Make generated factory request null save adapters. (#71)
and if so how to get old behavior back? :) Thanks!
Given:
Moshi moshi = new Moshi.Builder()
.add(Auto_ABV.typeAdapterFactory())
.build();
moshi.adapter(ABV.class).fromJson(jsonString);
Will get:
java.lang.IllegalArgumentException: Cannot serialize abstract class com.package.ABV
at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:58)
But expecting a new instance of AutoValue_ABV.class
.
This issue is that the create()
method of the generated JsonAdapter.Factory
does if (!(type instanceof ABV)) return null;
and since ABV.class
is an instance of Class
not ABV
, the factory doesn't indicate it can handle the deserialization.
I have a solution that works, though it isn't pretty (yet). Right now it uses com.squareup.moshi.Types#getRawType(Type)
reflectively (as it's package private). https://github.com/MariusVolkhart/auto-value-moshi/commit/554db9636d2cbe99a4367b35ececdd02d68b882e
Would appreciate feedback on whether or not to pursue this solution, either by requesting Moshi to make getRawType(Type)
public or by bundling the code for it.
In version 0.4.5
, it generates code along these lines:
public static final class MoshiJsonAdapter extends JsonAdapter<TextViewerCfg> {
private final JsonAdapter<String> syntaxAdapter;
public MoshiJsonAdapter(Moshi moshi) {
// warning: unchecked conversion
this.syntaxAdapter = adapter(moshi, String.class);
}
// warning: rawtype
private JsonAdapter adapter(Moshi moshi, Type adapterType) {
return moshi.adapter(adapterType);
}
...
These compile warnings are fixed by this:
private <T> JsonAdapter<T> adapter(Moshi moshi, Type adapterType) {
Open to a PR fixing this?
The underlying problem is this line. BestGuess does not cope well with uppercase package names.
Stacktrace:
Error:(14, 28) error: @autovalue processor threw an exception: java.lang.IllegalArgumentException: couldn't make a guess for org.example.Test.foo.MyClass
at com.squareup.javapoet.Util.checkArgument(Util.java:64)
at com.squareup.javapoet.ClassName.bestGuess(ClassName.java:159)
at com.ryanharter.auto.value.moshi.AutoValueMoshiExtension.generateClass(AutoValueMoshiExtension.java:149)
at com.google.auto.value.processor.AutoValueProcessor.processType(AutoValueProcessor.java:424)
at com.google.auto.value.processor.AutoValueProcessor.process(AutoValueProcessor.java:143)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:46)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:33)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:104)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:53)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:38)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:35)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:25)
at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:163)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:145)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:93)
at com.android.build.gradle.tasks.factory.AndroidJavaCompile.compile(AndroidJavaCompile.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:245)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:232)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Using auto-value-moshi:0.2.2
.
Generated code have problem with @JsonQualifier
annotation in classes inherited.
public interface MixinA {
@HexColor int color();
}
@AutoValue
public abstract class B implements MixinA {
}
Using generated JsonAdapter
will result in
java.lang.RuntimeException: No method named color()
When evaluating my Autovalue generated class (let's call it MyClass) the JsonAdapter.Factory create() method returns null instead of returning MyClass.jsonAdapter(moshi).
This happens because MyClass.class.isAssignableFrom(type.getClass())
evaluates aways to false.
I have a Kotlin auto-value class that implements parcelable and needs to be serialized by moshi. I'm using auto-value-parceleable and auto-value-moshi. I've followed the recommendation in issue #70 to include a @JvmStatic
annotation on my jsonAdapter factory method. However, the MoshiJsonAdapter
nested class is generated on $AutoValue_<class_name>
instead of AutoValue_<class_name>
.
That feels like a bug. My class looks like this:
@AutoValue
abstract class LockSelectionModel : Parcelable {
abstract fun brand(): String
companion object {
@JvmStatic fun jsonAdapter(moshi: Moshi): JsonAdapter<LockSelectionModel> =
`$AutoValue_LockSelectionModel`.MoshiJsonAdapter(moshi)
}
}
It just took me 1 hour to detect a stupid bug where my project wouldn't compile.
I had method of a primitive type annotated as @Nullable
.
The generated adapter was checking
if(value.primitiveField() != null){
...
I think the appropriate behavior for this extension would be to simply ignore the annotation on nullable methods.
Hi, while trying to migrate from Gson to Moshi, and auto-value-gson to auto-value-moshi, I realised that support for defaulting collections to empty is missing (see https://github.com/rharter/auto-value-gson#compiler-options).
Thanks for the library!
It'd be awesome if @MoshiAdapterFactory
would be in it's own artifact so that one does not have to use the following:
provided 'com.ryanharter.auto.value:auto-value-moshi:0.4.1'
to add the annotation to the classpath. The big disadvantage is that all of the other classes are also added to the class path (AutoValue components, possible Guava etc).
Given the class @AutoValue abstract class Foo<T>
, compilation fails when I include auto-value-moshi (apt 'com.ryanharter.auto.value:auto-value-moshi:0.2-SNAPSHOT'
).
Given this class:
@AutoValue
public abstract class Test {
public abstract int value();
public abstract Builder toBuilder();
public static Builder builder() {
return new AutoValue_Test.Builder();
}
@AutoValue.Builder
public interface Builder {
Builder value(int value);
Test build();
}
}
I get this error:
Error:(71, 14) error: constructor AutoValue_Test in class AutoValue_Test cannot be applied to given types;
required: int,Builder
found: Integer
reason: actual and formal argument lists differ in length
If I remove toBuilder()
it compiles fine.
Unless Ive missed it; There doesnt seem to be a way to create a list of objects through the MoshiAdapter that you generate.
What Im looking for:
@AutoValue
public static abstract class MyObject {
public abstract String value();
public static JsonAdapter<MyObject> jsonAdapterSingle(Moshi moshi){
//return ...
}
public static JsonAdapter<List<MyObject>> jsonAdapterList(Moshi moshi){
//return ...
}
}
auto-value-moshi requires a method like this:
public static JsonAdapter<MyAutoValueClass> jsonAdapter(Moshi moshi) { ... }
Are you open to a PR which would allow this?
static JsonAdapter<MyAutoValueClass> jsonAdapter(Moshi moshi) { ... }
With Java 9 modularity coming, I'd like the option to use Moshi as an implementation detail which is invisible to client code.
Generated JsonAdapter skips null values. AutoValueMoshiExtension
Is there a way I can overcome this ?
I would like the field to gave a default value. It is not a primitive type.
Hi,
I'd like to use auto-value-moshi on a pure java project. I thought it should be possible, since both autovalue and moshi are not Android dependent.
However, the plugin needs a gradle plugin, which works only with android/android-library project types:
com.neenbedankt.gradle.plugins:android-apt
Would it be possible to use another annotation processing plugin, so the tool's usage is not restricted to Android only?
This issue mirrors a similar request created for auto-value-gson
which can be found here.
Suggestion is to add annotation like this:
@AutoValue @Moshi public abstract class Foo {
}
Classes which are not annotated with @Moshi
won't get type adapter generated for them.
This causes a crash in the generated code, because it implicitly tries to downcast back to primitives and throws an exception like java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
.
The following code demonstrates the problem:
@AutoValue
public abstract class MyObject {
public abstract String name();
public static List<String> someOtherMethod() {
return null;
}
@NonNull
public static JsonAdapter<MyObject> jsonAdapter(@NonNull Moshi moshi) {
return new AutoValue_MyObject.MoshiJsonAdapter(moshi);
}
}
@MoshiAdapterFactory
public abstract class MyAdapterFactory implements JsonAdapter.Factory {
public static JsonAdapter.Factory create() {
return new AutoValueMoshi_MyAdapterFactory();
}
}
This will produce the following factory:
public final class AutoValueMoshi_MyAdapterFactory extends MyAdapterFactory {
@Override
public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) {
if (!annotations.isEmpty()) return null;
if (type.equals(MyObject.class)) {
return MyObject.someOtherMethod(moshi);
}
return null;
}
}
The tools have supported Java 7isms natively and with transparent if/else rewriting for 2 years now. This should be (much?) more efficient than naive if/elses.
Sort of an edge case, but putting it on your radar.
public abstract class A {
public enum Type { Apple, Banana }
abstract Type type();
}
Resulting error mentions something like:
Error:(28, 23) error: AutoValue_AJsonAdapterFactory is not abstract and does not override abstract method create(Type,Set<? extends Annotation>,Moshi) in Factory
Because the Type
in that method is incorrectly pointing to the inner class rather than java.lang.reflect.Type
I have been trying to use this moshi extension project but project building fails. Including a sample will be helpful.
Something like:
private final JsonAdapter<String> bar;
private final JsonAdapter<Map<String, String>> baz;
FooJsonAdapter(Moshi moshi) {
bar = moshi.adapter(String.class);
baz = moshi.adapter(Types.newParameterizedType(Map.class, String.class, String.class));
}
This saves having to look them up for every serialization/deserialization and also saves the creation of the parameterized type instance for lookup when generic types are used.
It also moves configuration exceptions to happen when the user looks up an adapter for their type rather than when serialization actually happens.
If model have a method with parameterized return type defined before moshi's typeAdapter method the annotation processor picks wrong method for factory generation.
Example:
import com.google.auto.value.AutoValue;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
@AutoValue
public abstract class Section {
public abstract int id();
public static TypeAdapter<Section> typeAdapter(Gson gson) {
return new AutoValue_Section.GsonTypeAdapter(gson);
}
public static JsonAdapter<Section> jsonAdapter(Moshi moshi) {
return new AutoValue_Section.MoshiJsonAdapter(moshi);
}
}
Trying to compile a pure java module and I have added
compileOnly 'com.ryanharter.auto.value:auto-value-moshi:0.4.0'
to my gradle file but it seems like my factory class isn't being generated...
This is the static method for my JsonAdapterFactory
class:
public static JsonAdapter.Factory create() { return new AutoValueMoshi_JsonAdapterFactory(); }
Would you be open to a PR that adds an @Ignore
annotation that AVM would use to discard annotated fields in its generated adapter? AFAIK this doesn't exist.
Related Moshi issue here #94.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.