One more thing, how to add default value information in reflect?

On Tue, Oct 18, 2011 at 11:14 AM, 常冰琳 <[email protected]> wrote:

> This should work in general.  An avro field can be promoted from a String
>> to a nullable String.  The inverse is not true.  A client that is expecting
>> a non-nullable string field response cannot read data serialized with a
>> nullable string.
>
>
> What I do in the demo is add a new nullable string in server side, not
> change a string to nullable string.
> I add a new field with default value using specific, and it works fine, so
> I suspect the reason that reflect doesn't work is that I didn't add default
> value to the nullable string field.
> Perhaps the default value for nullable field should be null by default?
>
>
> 2011/10/17 Scott Carey <[email protected]>
>
>> On 10/13/11 5:25 AM, "常冰琳" <[email protected]> wrote:
>>
>> Hi,
>> I try to use avro-ipc in my project and got a problem, if the server side
>> needs to upgrade,
>> add a few optional field to Request/Response object, or add a new method,
>> thus change the
>> schema.
>> I use reflect, add a new String field in Request class with @Nullable in
>> server side, keep client
>> side unchanged, but it won't to work.
>> I think protobuf supports this, just by adding new optional fields.
>> So does it possible or how to support backward compatibility in other way?
>>
>>
>>
>>  This should work in general.  An avro field can be promoted from a
>> String to a nullable String.  The inverse is not true.  A client that is
>> expecting a non-nullable string field response cannot read data serialized
>> with a nullable string.
>>
>> I am not familiar enough with the Protocol requestor or how it interacts
>> with the Reflect API to spot the issue.  I can't tell from the stack trace
>> if a resolving decoder is in use — which is required to resolve from one
>> schema to another.
>>
>> If you want the server side to evolve you can:
>> add new fields
>> remove fields (only if the field has a default on the client side)
>> promote fields as permitted (int -> long; string -> nullable string; etc.)
>> rename fields or other named types with aliases.
>>
>> Here is the protocol class
>>
>>
>> old:
>>
>>
>>
>> public interface SampleService {
>>   public static class Request {
>>     int id;
>>     String name;
>>     @Nullable
>>     String address;
>>
>>     public Request() {
>>       this(0, "null", null);
>>     }
>>
>>     public Request(int id, String name, String address) {
>>       this.id = id;
>>       this.name = name;
>>       this.address = address;
>>     }
>>
>>     public int getId() {
>>       return id;
>>     }
>>
>>     public String getName() {
>>       return name;
>>     }
>>
>>     public String getAddress() {
>>       return address;
>>     }
>>
>>   }
>>
>>   public static class Response {
>>     @Nullable
>>     String value;
>>
>>     public Response() {
>>       this("null");
>>     }
>>     public Response(String value) {
>>       this.value = value;
>>     }
>>
>>     public String getValue() {
>>       return value;
>>     }
>>   }
>>
>>   int fibonacci(int n);
>>   int sum(int [] nums, int base);
>>   Response complexCall(Request req);
>> }
>>
>>
>>
>>
>> new:
>>
>>
>> public interface SampleService {
>>   public static class Request {
>>     int id;
>>     String name;
>>     @Nullable
>>     String address;
>>     @Nullable
>>     String address2;
>>
>>     public Request() {
>>       this(0, "null", null, null);
>>     }
>>
>>     public Request(int id, String name, String address, String address2) {
>>       this.id = id;
>>       this.name = name;
>>       this.address = address;
>>       this.address2 = address2;
>>     }
>>
>>     public int getId() {
>>       return id;
>>     }
>>
>>     public String getName() {
>>       return name;
>>     }
>>
>>     public String getAddress() {
>>       return address;
>>     }
>>
>>     public String getAddress2() {
>>       return address2;
>>     }
>>
>>   }
>>
>>   public static class Response {
>>     @Nullable
>>     String value;
>>
>>     public Response() {
>>       this("null");
>>     }
>>     public Response(String value) {
>>       this.value = value;
>>     }
>>
>>     public String getValue() {
>>       return value;
>>     }
>>   }
>>
>>   int fibonacci(int n);
>>   int sum(int [] nums, int base);
>>   Response complexCall(Request req);
>> }
>>
>>
>> Here is the error message:
>>
>> Exception in thread "main" org.apache.avro.AvroRuntimeException:
>> org.apache.avro.AvroTypeException: Found {
>>   "type" : "record",
>>   "name" : "Request",
>>   "namespace" : "com.mycompany.app.SampleService$",
>>   "fields" : [ {
>>     "name" : "id",
>>     "type" : "int"
>>   }, {
>>     "name" : "name",
>>     "type" : "string"
>>   }, {
>>     "name" : "address",
>>     "type" : [ "null", "string" ]
>>   } ]
>> }, expecting {
>>   "type" : "record",
>>   "name" : "Request",
>>   "namespace" : "com.mycompany.app.SampleService$",
>>   "fields" : [ {
>>     "name" : "id",
>>     "type" : "int"
>>   }, {
>>     "name" : "name",
>>     "type" : "string"
>>   }, {
>>     "name" : "address",
>>     "type" : [ "null", "string" ]
>>   }, {
>>     "name" : "address2",
>>     "type" : [ "null", "string" ]
>>   } ]
>> }
>> at
>> org.apache.avro.ipc.specific.SpecificRequestor.readError(SpecificRequestor.java:126)
>>  at
>> org.apache.avro.ipc.Requestor$Response.getResponse(Requestor.java:555)
>> at
>> org.apache.avro.ipc.Requestor$TransceiverCallback.handleResult(Requestor.java:360)
>>  at
>> org.apache.avro.ipc.Requestor$TransceiverCallback.handleResult(Requestor.java:323)
>> at
>> org.apache.avro.ipc.NettyTransceiver$NettyClientAvroHandler.messageReceived(NettyTransceiver.java:382)
>>  at
>> org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80)
>> at
>> org.apache.avro.ipc.NettyTransceiver$NettyClientAvroHandler.handleUpstream(NettyTransceiver.java:364)
>>  at
>> org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:545)
>> at
>> org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:754)
>>  at
>> org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:302)
>> at
>> org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:317)
>>  at
>> org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:299)
>> at
>> org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216)
>>  at
>> org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80)
>> at
>> org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:545)
>>  at
>> org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:540)
>> at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
>>  at
>> org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
>> at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
>>  at
>> org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
>> at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
>>  at
>> org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
>> at
>> org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:44)
>>  at
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>> at
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>  at java.lang.Thread.run(Thread.java:680)
>>
>>
>

Reply via email to