Out of blue, I found the Java class generated out of an Avro schema stop working. Flink complains “Expecting type to be a PojoTypeInfo” for the generated class. Dig a little deeper, I discovered that a class must first be recognized a POJO type first, then a AvroTypeInfo
can be derived.
I have been successful using Avro-generated class in Flink for a while without any hiccups, so this incident is very bizarre.
One peculiarity for the troublesome Avro schema is that it contains a record with an empty fields
, something like this:
in .avdl
:
record Foo { }
in .avsc
:
{
"name": "Foo",
"type": "record",
"fields": []
}
Long story short, I discovered a piece of code in Flink which decides what Type a given class should be:
// org.apache.flink.api.java.typeutils.TypeExtractor
// line 2064 to 2073
List<Field> fields = getAllDeclaredFields(clazz, false);
if (fields.size() == 0) {
LOG.info(
"No fields were detected for "
+ clazz
+ " so it cannot be used as a POJO type "
+ "and must be processed as GenericType. {}",
GENERIC_TYPE_DOC_HINT);
return new GenericTypeInfo<>(clazz);
}
The four tests for recognizing POJOs from Flink’s documentation do not exclude the case for a class without fields. Concerning fields of a class, it says:
All fields are either public or must be accessible through getter and setter functions. For a field called foo the getter and setter methods must be named getFoo() and setFoo().
Seems like “a class must have declared fields” is an undocumented rule.
Apart from that, what is the reason to exclude a zero field class? Just for the sake of defensive coding, or there is major differences between a zero-field class and an alternative?