You may be able to use the @Stringable annotation. Avro's reflection is not that extensible beyond basic types at the moment. Please file an enhancement request for BigDecimal support in JIRA. Thanks!
On 1/18/12 12:34 PM, "Jian Fang" <[email protected]> wrote: > Hi, > > I tried to use Avro 1.6.1 for my existing domain classes with reflection, but > the BigDecimal type caused some trouble for me. > > Take the following code as an example, > > public class Parent { > > private String name; > > private int age; > > private Date birthday; > > public String getName() { > return name; > } > > public void setName(String name) { > this.name <http://this.name> = name; > } > > public int getAge() { > return age; > } > > public void setAge(int age) { > this.age = age; > } > > public Date getBirthday() { > return birthday; > } > > public void setBirthday(Date birthday) { > this.birthday = birthday; > } > } > > public class Child extends Parent { > > private BigDecimal salary; > > public BigDecimal getSalary() { > return salary; > } > > public void setSalary(BigDecimal salary) { > this.salary = salary; > } > } > > I have two classes, the Parent class does not have the BigDecimal type, but > the Child does have. > > I created a test case as follows: > > public class AvroSchema_UnitTest { > > @Test > public void testBigDecimal() { > ReflectData reflectData = ReflectData.AllowNull.get(); > Schema schema = reflectData.getSchema(Parent.class); > System.out.println("Parent"); > System.out.println(schema.toString()); > schema = reflectData.getSchema(Child.class); > System.out.println("Parent"); > System.out.println(schema.toString()); > } > } > > Run it and here is the following output: > > Parent > {"type":"record","name":"Parent","namespace":"com.barnesandnoble.domain","fiel > ds":[{"name":"name","type":["null","string"],"default":null},{"name":"age","ty > pe":["null","int"],"default":null},{"name":"birthday","type":["null",{"type":" > record","name":"Date","namespace":"java.util","fields":[]}],"default":null}]} > > org.apache.avro.AvroRuntimeException: java.lang.NoSuchFieldException: SCHEMA$ > at > org.apache.avro.specific.SpecificData.createSchema(SpecificData.java:193) > at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:249) > at > org.apache.avro.reflect.ReflectData.createFieldSchema(ReflectData.java:363) > at > org.apache.avro.reflect.ReflectData$AllowNull.createFieldSchema(ReflectData.ja > va:68) > at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:292) > at org.apache.avro.specific.SpecificData.getSchema(SpecificData.java:134) > at > com.barnesandnoble.domain.AvroSchema_UnitTest.testBigDecimal(AvroSchema_UnitTe > st.java:58) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j > ava:25) > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.ja > va:44) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.jav > a:15) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java > :41) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java: > 20) > at > org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: > 76) > at > org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: > 50) > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) > at org.junit.runners.ParentRunner.run(ParentRunner.java:236) > at org.junit.runner.JUnitCore.run(JUnitCore.java:157) > at > com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRun > ner.java:71) > at > com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStart > er.java:199) > at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) > Caused by: java.lang.NoSuchFieldException: SCHEMA$ > at java.lang.Class.getDeclaredField(Class.java:1882) > at > org.apache.avro.specific.SpecificData.createSchema(SpecificData.java:185) > ... 31 more > > As you can see, the Parent class is fine, but the Child class throws an > exception because of the BigDecimal type. > > Is this a bug? How to get around this if I am not able to change the existing > domain classes. > > > Thanks, > > John > > > > > >
