Matthew McMahon created AVRO-2840:
-------------------------------------

             Summary: Maven allow Custom Logical Types for generated code
                 Key: AVRO-2840
                 URL: https://issues.apache.org/jira/browse/AVRO-2840
             Project: Apache Avro
          Issue Type: Improvement
          Components: java
            Reporter: Matthew McMahon


So, as seen in AVRO-2498 we now have the ability in 1.9, at least using the 
Maven tools, to have generated classes with a field of type UUID. For some 
background, the secret sauce to get this working is:
 * Set the logicalType of the field to 'uuid' and type to 'string'
 * In the maven plugin configuration, add an item to <customConversions> with 
the value org.apache.avro.Conversions$UUIDConversion

I attempted this with a custom type of my own (in this case, joda Money) first 
by implementing a CustomConversion<Money> class that created a new LogicalType 
called "money". This did not work, though, because although the maven mojo 
correctly added the CustomConversion to the SpecificCompiler, when the compiler 
parses the schema and sees the logicalType of type "money", it attempts to look 
up the LogicalType from LogicalTypes the LogicalType is not registered and it 
ignores it, which causes the field within the Schema to not have a logicalType. 
Without a logicalType, the compiler does not consider it a 
"UsedConversionClass" (see SpecificCompiler.getUsedConversionClass()) and they 
velocity template doesn't write the class with the custom field type.

Trying to be clever, I attempted to work around this by putting a static 
initializer in my CustomConversion class which called LogicalTypes.register(). 
Unfortunately for me, the maven plugin doesn't load any of the classes 
specified in <customConversions> until AFTER it has parsed a schema.

Obviously, putting a static initializer inside of a CustomConversion should not 
be part of a solution to this issue, but I propose a very simple solution:
 * Add a logicalTypes property to AbstractAvroMojo, with items of a new type, 
LocalTypeDefinition. That type will have a name and a logicalTypeFactory.
 * Upon startup of the mojo, iterate through each item and call 
LogicalTypes.register() on each, passing the indicated name and a new instance 
of the indicated logicalTypeFactory class.
 * At this point, the existing logic will treat the new custom type the same as 
"uuid" is treated and will generate SpecificRecord classes with fields of that 
type.

I could implement this pretty trivially, if there's an appetite for it. This 
would seem to be 100% backwards compatible.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to