[
https://issues.apache.org/jira/browse/BETWIXT-61?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Stephen Halsey updated BETWIXT-61:
----------------------------------
Attachment: WithBugBean.java
WithoutBugBean.java
TestBetwixtArrayBugUnit.java
Here are the class files as files (easier for you than copying out of my
comment)
> Array in bean causes element after to not be set
> ------------------------------------------------
>
> Key: BETWIXT-61
> URL: https://issues.apache.org/jira/browse/BETWIXT-61
> Project: Commons Betwixt
> Issue Type: Bug
> Environment: Windows XP, Suns Java 1.5.0_07, Betwixt Version 0.8
> Source.
> Reporter: Stephen Halsey
> Attachments: TestBetwixtArrayBugUnit.java, WithBugBean.java,
> WithoutBugBean.java
>
>
> Hi,
> I am having a problem with a class that has arrays in it and writing and
> reading them using betwixt. I have tracked down the problem and created a
> simple unit test with the 3 classes below that demonstate this. If you
> create a new org.apache.commons.betwixt.arraybug package in your src/test
> folder of you betwixt source code and put these classes in you should be able
> to run the tests.
> I have put an explanation of what the test does at the top of the
> TestBetwixtArrayBugUnit class.
> I'm sorry if I've just used the wrong settings or something, but I based it
> on the code from the examples page at
> http://commons.apache.org/betwixt/guide/examples.html for doing a round trip
> on a simple bean.
> I'm not sure, but there is a chance this could be related to the error
> someone reported at:-
> http://markmail.org/message/ofm3yp7gf7auhfcp
> because I may have seen the EmptyStackException under certain circumstances
> too whilst developing this test, but in this test you will see no exception
> is generated, the value just comes out null for the xxx parameter because it
> is alphabetically after the array parameter, which is actually more worrying
> as its a lot harder to spot.
> If you would like me to I can do a bit more work and get sample debug output
> to try and work out why it is doing what it is doing?
> thanks
> Steve
> package org.apache.commons.betwixt.arraybug;
> import java.beans.IntrospectionException;
> import java.io.IOException;
> import java.io.StringReader;
> import java.io.StringWriter;
> import junit.framework.TestCase;
> import org.apache.commons.betwixt.io.BeanReader;
> import org.apache.commons.betwixt.io.BeanWriter;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.xml.sax.SAXException;
> /*
> * TestBetwixtArrayBugUnit class.
> *
> * This class contains two unit tests. One will run
> * successfully and do a round trip on a simple bean,
> * the other will fail because a value has not been set
> * on reading a bean out of xml using betwixt. This
> * seems to happens when a String array is read
> * in, and means that all variables alphabeticically
> * after is will be null. From looking at the output
> * with logging set to debug you can see that the xxx
> * parameter value does not have the "Calling setter method"
> * part in it when the test fails.
> *
> *
> *
> */
> public class TestBetwixtArrayBugUnit extends TestCase {
>
> static Log log = LogFactory.getLog( TestBetwixtArrayBugUnit.class );
> public void testRoundTripThatWorks() throws IOException, SAXException,
> IntrospectionException
> {
> log.info("In this test we test a round trip of an object that works.
> We create a WithoutBugBean object, convert " +
> "it to xml, convert from xml back into a new
> WithoutBugBean object "
> + " and check that they are equal and we find that they
> are and so the test passes.");
> String aOriginal = "aString";
> String xxxOriginal = "xxxString";
> WithoutBugBean withoutBugBeanOriginal = new
> WithoutBugBean(aOriginal,xxxOriginal);
>
> log.info("Starting off with withoutBugBeanOriginal = " +
> withoutBugBeanOriginal);
> // Start by preparing the writer
> // We'll write to a string
> StringWriter outputWriter = new StringWriter();
>
> // Betwixt just writes out the bean as a fragment
> // So if we want well-formed xml, we need to add the prolog
> outputWriter.write("<?xml version='1.0' ?>\n");
>
> // Create a BeanWriter which writes to our prepared stream
> BeanWriter beanWriter = new BeanWriter(outputWriter);
>
> // Configure betwixt
> // For more details see java docs or later in the main documentation
>
> beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
> beanWriter.getBindingConfiguration().setMapIDs(false);
> beanWriter.enablePrettyPrint();
> // If the base element is not passed in, Betwixt will guess
> // But let's write example bean as base element 'person'
> beanWriter.write("WithoutBugBean", withoutBugBeanOriginal);
>
> // Write to System.out
> // (We could have used the empty constructor for BeanWriter
> // but this way is more instructive)
> String xmlString = outputWriter.toString();
>
> // Betwixt writes fragments not documents so does not automatically
> close
> // writers or streams.
> // This example will do no more writing so close the writer now.
> outputWriter.close();
>
> log.info(" xmlString = " + xmlString);
>
>
>
> // First construct the xml which will be read in
> // For this example, read in from a hard coded string
> StringReader xmlReader = new StringReader(xmlString);
>
> // Now convert this to a bean using betwixt
> // Create BeanReader
> BeanReader beanReader = new BeanReader();
>
> // Configure the reader
> // If you're round-tripping, make sure that the configurations are
> compatible!
>
> beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
> beanReader.getBindingConfiguration().setMapIDs(false);
>
> // Register beans so that betwixt knows what the xml is to be
> converted to
> // Since the element mapped to a PersonBean isn't called the same
> // as Betwixt would have guessed, need to register the path as well
> beanReader.registerBeanClass("WithoutBugBean", WithoutBugBean.class);
>
> // Now we parse the xml
> WithoutBugBean withoutBugBeanNew = (WithoutBugBean)
> beanReader.parse(xmlReader);
>
> log.info("Got back withoutBugBeanNew = " + withoutBugBeanNew);
>
> log.info("Now checking that withoutBugBeanNew equals
> withoutBugBeanOriginal");
> assertTrue(withoutBugBeanNew.equals(withoutBugBeanOriginal));
> }
>
>
> public void testRoundTripThatDoesNotWorkWithArray() throws IOException,
> SAXException, IntrospectionException
> {
> log.info("In this test we test a round trip of an object with an array
> in that DOES NOT work. " +
> "As before we create a WithBugBean object, convert " +
> "it to xml, convert from xml back into a new
> WithBugBean object "
> + " and check that they are equal and we find that they
> are NOT because one of the elements is null.");
> String aOriginal = "aString";
> String[] littleArray = new String[2];
> littleArray[0] = "littleArrayString0";
> littleArray[1] = "littleArrayString1";
> String xxxOriginal = "xxxString";
> WithBugBean withBugBeanOriginal = new
> WithBugBean(aOriginal,littleArray,xxxOriginal);
>
> log.info("Starting off with withBugBeanOriginal = " +
> withBugBeanOriginal);
> // Start by preparing the writer
> // We'll write to a string
> StringWriter outputWriter = new StringWriter();
>
> // Betwixt just writes out the bean as a fragment
> // So if we want well-formed xml, we need to add the prolog
> outputWriter.write("<?xml version='1.0' ?>\n");
>
> // Create a BeanWriter which writes to our prepared stream
> BeanWriter beanWriter = new BeanWriter(outputWriter);
>
> // Configure betwixt
> // For more details see java docs or later in the main documentation
>
> beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
> beanWriter.getBindingConfiguration().setMapIDs(false);
> beanWriter.enablePrettyPrint();
> // If the base element is not passed in, Betwixt will guess
> // But let's write example bean as base element 'person'
> beanWriter.write("WithBugBean", withBugBeanOriginal);
>
> // Write to System.out
> // (We could have used the empty constructor for BeanWriter
> // but this way is more instructive)
> String xmlString = outputWriter.toString();
>
> // Betwixt writes fragments not documents so does not automatically
> close
> // writers or streams.
> // This example will do no more writing so close the writer now.
> outputWriter.close();
>
> log.info(" xmlString = " + xmlString);
>
>
>
> // First construct the xml which will be read in
> // For this example, read in from a hard coded string
> StringReader xmlReader = new StringReader(xmlString);
>
> // Now convert this to a bean using betwixt
> // Create BeanReader
> BeanReader beanReader = new BeanReader();
>
> // Configure the reader
> // If you're round-tripping, make sure that the configurations are
> compatible!
>
> beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
> beanReader.getBindingConfiguration().setMapIDs(false);
>
> // Register beans so that betwixt knows what the xml is to be
> converted to
> // Since the element mapped to a PersonBean isn't called the same
> // as Betwixt would have guessed, need to register the path as well
> beanReader.registerBeanClass("WithBugBean", WithBugBean.class);
>
> // Now we parse the xml
> WithBugBean withBugBeanNew = (WithBugBean)
> beanReader.parse(xmlReader);
>
> log.info("Got back withBugBeanNew = " + withBugBeanNew);
>
> log.info("Now checking that withBugBeanNew equals
> withBugBeanOriginal.");
> log.info("At this point you should see the test FAIL because xxx has
> been set to null "
> + " because it is alphabetically after the littleArray
> and betwixt suddenly seems to stop setting variables once "
> + " it hits this littleArray");
> assertTrue(withBugBeanNew.equals(withBugBeanOriginal));
> }
>
> }
> package org.apache.commons.betwixt.arraybug;
> /*
> * WithBugBean class.
> * This is the bean that DOES demonstrate the betwixt bug with arrays because
> the xxx
> * variable gets set to null when you try to read it in.
> */
> public class WithBugBean {
>
> private String a;
> //This class has the additional littleArray value.
> String[] littleArray;
> private String xxx;
>
> public WithBugBean()
> {
> }
>
> public WithBugBean(String a, String[] littleArray, String xxx)
> {
> setA(a);
> setLittleArray(littleArray);
> setXxx(xxx);
> }
>
>
> public String toString() {
> return "[" + this.getClass().getName() + ": a=" + a + " xxx = " +
> xxx + "]";
> }
> public String getA() {
> return a;
> }
> public void setA(String a) {
> this.a = a;
> }
> public String getXxx() {
> return xxx;
> }
> public void setXxx(String xxx) {
> this.xxx = xxx;
> }
>
> public boolean equals( Object obj ) {
> if ( obj == null ) return false;
> return this.hashCode() == obj.hashCode();
> }
>
> public int hashCode() {
> return toString().hashCode();
> }
> public String[] getLittleArray() {
> return littleArray;
> }
> public void setLittleArray(String[] littleArray) {
> this.littleArray = littleArray;
> }
> }
> package org.apache.commons.betwixt.arraybug;
> /*
> * WithoutBugBean class.
> * This is the bean that does not demonstrate the betwixt bug with arrays.
> */
> public class WithoutBugBean {
>
> private String a;
> private String xxx;
>
> public WithoutBugBean()
> {
> }
>
> public WithoutBugBean(String a, String xxx)
> {
> setA(a);
> setXxx(xxx);
> }
>
>
> public String toString() {
> return "[" + this.getClass().getName() + ": a=" + a + " xxx = " +
> xxx + "]";
> }
> public String getA() {
> return a;
> }
> public void setA(String a) {
> this.a = a;
> }
> public String getXxx() {
> return xxx;
> }
> public void setXxx(String xxx) {
> this.xxx = xxx;
> }
>
> public boolean equals( Object obj ) {
> if ( obj == null ) return false;
> return this.hashCode() == obj.hashCode();
> }
>
> public int hashCode() {
> return toString().hashCode();
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.