commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b p <trashspam2...@yahoo.com>
Subject Re: [betwixt]: Cycles cause StackOverflowError when registering bean
Date Thu, 15 Jan 2004 17:54:17 GMT
Hi Robert,
 
I was able to get the refactoring branch, build a jar and successfully run my tests.  I'll
work off your refactoring branch for now.  Thanks for your help.
 
I did run into another issue(in both the HEAD and Refactoring branch).  It doesn't seem that
ids are being written in the XML even if I call:  BeanWriter.getBindingConfiguration().setMapIDs(true).
 This causes odd XML that has references to unknown objects.  The XML looks like: 
<?xml version='1.0' ?>
  <PersonTest>
    <address>
      <reference>
        <person idref="1"/>
      </reference>
      <streetAddress>1221 Washington Street</streetAddress>
    </address>
    <name>John Doe</name>
  </PersonTest>

I decided to dive into betwixt source code a bit and found the problem in the ElementAttributes
class.  I made a quick test case and came up with a simple fix that is working for me.  However,
it did break other unit tests because those unit tests are assuming the ids will not be written,
but are not calling setMapIDs(false) (it seems to me that the unit tests are wrong).  I included
a patch below with the test and fix that you can use if you find it helpful.
 
-Brian
 
Index: betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java,v
retrieving revision 1.22.2.1
diff -u -r1.22.2.1 AbstractBeanWriter.java
--- betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java 13 Jan 2004 21:49:46
-0000 1.22.2.1
+++ betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java 15 Jan 2004 17:48:31
-0000
@@ -941,10 +941,15 @@
                             Context context, 
                             String idAttributeName,
                             String idValue) {
-            attributes = descriptor.getAttributeDescriptors();
+            AttributeDescriptor[] existingAttributes = descriptor.getAttributeDescriptors();
             this.context = context;
             this.idValue = idValue;
             this.idAttributeName = idAttributeName;
+            attributes = new AttributeDescriptor[existingAttributes.length + 1];
+            attributes[0] = new AttributeDescriptor(this.idAttributeName);
+            for (int i=0;i<existingAttributes.length;i++) {
+              attributes[i+1] = existingAttributes[i];
+            }
         }
         
         /**
Index: betwixt/src/test/org/apache/commons/betwixt/recursion/TestRecursion.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/betwixt/src/test/org/apache/commons/betwixt/recursion/TestRecursion.java,v
retrieving revision 1.13.2.1
diff -u -r1.13.2.1 TestRecursion.java
--- betwixt/src/test/org/apache/commons/betwixt/recursion/TestRecursion.java 14 Jan 2004 22:51:35
-0000 1.13.2.1
+++ betwixt/src/test/org/apache/commons/betwixt/recursion/TestRecursion.java 15 Jan 2004 17:48:32
-0000
@@ -62,6 +62,7 @@
 package org.apache.commons.betwixt.recursion;
 
 import java.io.StringWriter;
+import java.io.StringReader;
 import java.io.Writer;
 import java.util.List;
 
@@ -378,5 +379,39 @@
    fail("Expected registration to succeed");
   }
  }
+
+ public void  testCycleReferences() throws Exception {
+  PersonTest person = new PersonTest();
+  person.setName("John Doe");
+  AddressTest address = new AddressTest();
+  address.setStreetAddress("1221 Washington Street");
+  person.setAddress(address);
+  ReferenceTest reference = new ReferenceTest();
+  reference.setPerson(person);
+  address.setReference(reference);
+
+  StringWriter outputWriter = new StringWriter();
+
+  outputWriter.write("<?xml version='1.0' ?>\n");
+  BeanWriter beanWriter = new BeanWriter(outputWriter);
+  beanWriter.enablePrettyPrint();
+  beanWriter.getBindingConfiguration().setMapIDs(true);
+  beanWriter.write(person);   
+
+  BeanReader beanReader = new BeanReader();
+
+  // Configure the reader
+  beanReader.registerBeanClass(PersonTest.class);
+  beanReader.registerBeanClass(AddressTest.class);
+  beanReader.registerBeanClass(ReferenceTest.class);
+
+  StringReader xmlReader = new StringReader(outputWriter.toString());
+
+  //Parse the xml
+  PersonTest result = (PersonTest)beanReader.parse(xmlReader);
+  assertSame("Cycle did not result in the same reference", result, result.getAddress().getReference().getPerson());
+
+  }
+
 }
 

robert burrell donkin <robertburrelldonkin@blueyonder.co.uk> wrote:
hi brian

thanks for the test case (i probably wouldn't have tracked it down 
otherwise). i've taken quite a good look at the problem and the bad 
news is that it's not really worth fixing on head (it'd be very 
difficult without break other stuff). the design of that part of the 
system has been completely refactored on the branch and the branch does 
not have this problem.

if you can't wait for the refactored branch to be merged into the HEAD 
(which will probably be in some weeks time), you're going to need to 
get hold of the source from CVS.

one option is to roll your own jar based on the branch 
(REFACTORING-BRANCH_2004-01-13). the code is very messy and there's a 
lot more refactoring to come (so the interfaces are likely to change in 
a backwards compatible way) but only one unit test fails.

alternative, you could try to patch the HEAD source in a way that will 
(probably) break some of betwixt's features that you don't use. i will 
give you some hints but i need to concentrate on getting the 
refactoring finished and so i can't spend too long.

- robert

On 13 Jan 2004, at 23:08, b p wrote:

> I am assuming that by "donating your code" you mean the test case I 
> included in my previous message which can certainly be donated to ASF.
>
> If you find it is possible, a patch to fix the problem would be 
> appreciated.
>
> Thanks for your responses,
> Brian
>
> robert burrell donkin wrote:
> darn. it's fixed on the refactoring branch i've been working on for a
> long while now but probably not on head. if you're cool about donating
> your code to the ASF i'll take a look and see about creating a patch
> for HEAD. (i'm not promising: if it looks too difficult, i'll probably
> concentrate on improving the refactored stuff.)
>
> - robert
>
> On 13 Jan 2004, at 21:51, b p wrote:
>
>> Hi,
>>
>> I was using the binary distribution from last night
>> (commons-betwixt-20040113.zip). I just tried building locally from
>> the the CVS Head and saw the same behavior.
>>
>> Below I included a small test that causes the StackOverflowError.
>>
>> Thanks,
>> Brian
>>
>>
>>
>> ------------------------------------------
>> public class TestBetwixt extends TestCase {
>>
>> public void testCycle() throws IntrospectionException, SAXException,
>> IOException {
>> BeanReader beanReader = new BeanReader();
>> beanReader.registerBeanClass(PersonTest.class);
>> }
>>
>> public static Test suite() {
>> return new TestSuite(TestCycle.class);
>> }
>> }
>>
>> ---------------------------------------------
>> public class PersonTest {
>> private String name;
>> private AddressTest address;
>> public String getName() {
>> return name;
>> }
>> public void setName(String name) {
>> this.name = name;
>> }
>> public AddressTest getAddress() {
>> return address;
>> }
>> public void setAddress(AddressTest address) {
>> this.address = address;
>> }
>> }
>>
>> ----------------------------------------------------
>> public class AddressTest {
>> private String streetAddress;
>> private ReferenceTest reference;
>> public String getStreetAddress() {
>> return streetAddress;
>> }
>> public void setStreetAddress(String streetAddress) {
>> this.streetAddress = streetAddress;
>> }
>> public ReferenceTest getReference() {
>> return reference;
>> }
>> public void setReference(ReferenceTest reference) {
>> this.reference = reference;
>> }
>> }
>>
>> -----------------------------------------------------
>> public class ReferenceTest {
>> private PersonTest person = null;
>> public PersonTest getPerson() {
>> return person;
>> }
>> public void setPerson(PersonTest person) {
>> this.person = person;
>> }
>> }
>>
>>
>>
>> robert burrell donkin wrote:
>> hi
>>
>> which version are you using? (i have a feeling that this bug has been
>> fixed already but i might be wrong...)
>>
>> if you're using the alpha, i'd suggest upgrading to CVS HEAD (you'll
>> need commons-beanutils 1.6.1 and commons-digester 1.5).
>>
>> - robert
>>
>> On 13 Jan 2004, at 19:38, b p wrote:
>>
>>> Hi,
>>>
>>> I have been investigating Betwixt and run into an issue with cycles.
>>> I have 3 beans with a cycle:
>>> A->-B
>>> B->C
>>> C->A
>>>
>>> I'm able to generate XML successfully, but not read it. When I call
>>> BeanReader.registerBeanClass(A) I get a StackOverflowError (printed
>>> below). If I take out the cycle, it works fine. I performed the test
>>> using the binary distribution 20040113.
>>>
>>> Does betwixt support cycles? If so, is there something specific I
>>> need to do to avoid what appears to be a recursive infinite loop?
>>>
>>> Thanks in advance,
>>>
>>> Brian
>>>
>>> java.lang.StackOverflowError
>>> at java.lang.Object.hashCode(Native Method)
>>> at java.util.HashMap.hash(HashMap.java:261)
>>> at java.util.HashMap.get(HashMap.java:317)
>>> at
>>> org.apache.commons.betwixt.registry.DefaultXMLBeanInfoRegistry.get(De 
>>> f
>>> a
>>> ultXMLBeanInfoRegistry.java:88)
>>> at
>>> org.apache.commons.betwixt.XMLIntrospector.introspect(XMLIntrospector 
>>> .
>>> j
>>> ava:326)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.getElementDe 
>>> s
>>> c
>>> riptor(BeanRuleSet.java:448)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addChildRule 
>>> s
>>> (
>>> BeanRuleSet.java:307)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:515)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:495)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addChildRule 
>>> s
>>> (
>>> BeanRuleSet.java:402)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:515)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:495)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addChildRule 
>>> s
>>> (
>>> BeanRuleSet.java:402)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:515)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addRule(Bean 
>>> R
>>> u
>>> leSet.java:495)
>>> at
>>> org.apache.commons.betwixt.io.BeanRuleSet$ReadingContext.addChildRule 
>>> s
>>> (
>>> BeanRuleSet.java:402)
>>> ...
>>>
>>>
>>>
>>> ---------------------------------
>>> Do you Yahoo!?
>>> Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-user-help@jakarta.apache.org
>>
>>
>> ---------------------------------
>> Do you Yahoo!?
>> Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org
>
>
> ---------------------------------
> Do you Yahoo!?
> Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


---------------------------------
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message