[ https://issues.apache.org/jira/browse/AVRO-1212?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sébastien Launay updated AVRO-1212: ----------------------------------- Status: Patch Available (was: Open) Patch fixing the issue by: - converting annotated List and Java array to ARRAY type with union component type - converting annotated Map to MAP type with union value type - detecting double \@Union to prevent issues - test cases to reproduce the issue and detect future regressions Note that: - it is not possible to define a union of Map or List with that approach - annotating nested List/Map/Array with \@Union will only be used for the leaf components - @Nullable on the other hand will be applied to the collection (to keep things backward compatible) Patch is attached but can be found here: https://github.com/slaunay/avro/commits/fix/AVRO-1212-union-collections > Protocol schema generated from reflection does not support @Union with > collections > ---------------------------------------------------------------------------------- > > Key: AVRO-1212 > URL: https://issues.apache.org/jira/browse/AVRO-1212 > Project: Avro > Issue Type: Bug > Components: java > Affects Versions: 1.7.2 > Reporter: Sébastien Launay > Attachments: AVRO-1212-union-with-collections-2012-11-28.patch > > > An interface using {{@Union}} for collections (Map, List, Java array) like > this one: > {code:java} > public interface P0 { > @Union({String.class,Integer.class}) List<Object> > foo(@Union({Integer.class,Long.class}) List<Number> l); > } > {code} > will produce the following schema where the lists have been erased by the > component unions: > {code:javascript} > { > "protocol" : "P0", > "namespace" : "", > "types" : [ { > "type" : "record", > "name" : "Number", > "namespace" : "java.lang", > "fields" : [ ] > } ], > "messages" : { > "foo" : { > "request" : [ { > "name" : "l", > "type" : [ "int", "long" ] > } ], > "response" : [ "string", "int" ] > } > } > } > {code} > instead of: > {code:javascript} > { > "protocol" : "P0X", > "namespace" : "", > "types" : [ { > "type" : "record", > "name" : "Object", > "namespace" : "java.lang", > "fields" : [ ] > }, { > "type" : "record", > "name" : "Number", > "namespace" : "java.lang", > "fields" : [ ] > } ], > "messages" : { > "foo" : { > "request" : [ { > "name" : "l", > "type" : { > "type" : "array", > "items" : [ "int", "long" ], > "java-class" : "java.util.List" > } > } ], > "response" : { > "type" : "array", > "items" : [ "string", "int" ], > "java-class" : "java.util.List" > } > } > } > } > {code} > This leads to exceptions when writing a response like List<R1|R2>: > {noformat} > org.apache.avro.UnresolvedUnionException: Not in union > [{"type":"record","name":"R1"},{"type":"record","name":"R2"}]: [R1@19f03d7] > at > org.apache.avro.generic.GenericData.resolveUnion(GenericData.java:542) > ~[avro-1.7.2.jar:1.7.2] > at > org.apache.avro.generic.GenericDatumWriter.resolveUnion(GenericDatumWriter.java:137) > ~[avro-1.7.2.jar:1.7.2] > at > org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:70) > ~[avro-1.7.2.jar:1.7.2] > at > org.apache.avro.reflect.ReflectDatumWriter.write(ReflectDatumWriter.java:104) > ~[avro-1.7.2.jar:1.7.2] > at > org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:57) > ~[avro-1.7.2.jar:1.7.2] > at > org.apache.avro.ipc.generic.GenericResponder.writeResponse(GenericResponder.java:58) > ~[avro-ipc-1.7.2.jar:1.7.2] > at org.apache.avro.ipc.Responder.respond(Responder.java:164) > [avro-ipc-1.7.2.jar:1.7.2] > at org.apache.avro.ipc.Responder.respond(Responder.java:99) > [avro-ipc-1.7.2.jar:1.7.2] > at > org.apache.avro.ipc.ResponderServlet.doPost(ResponderServlet.java:48) > [avro-ipc-1.7.2.jar:1.7.2] > at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) > [servlet-api-2.5-20081211.jar:na] > at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) > [servlet-api-2.5-20081211.jar:na] > at > org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:401) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) > [jetty-6.1.26.jar:6.1.26] > at org.mortbay.jetty.Server.handle(Server.java:322) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945) > [jetty-6.1.26.jar:6.1.26] > at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756) > [jetty-6.1.26.jar:6.1.26] > at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) > [jetty-6.1.26.jar:6.1.26] > at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410) > [jetty-6.1.26.jar:6.1.26] > at > org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) > [jetty-util-6.1.26.jar:6.1.26] > {noformat} -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira