[ 
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.

Reply via email to