marcusaram / snakeyaml

Automatically exported from code.google.com/p/snakeyaml
Apache License 2.0
1 stars 0 forks source link

Cannot create JavaBean containing custom object with no copy constructor #12

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This fails on SnakeYAML-1.3. On 1.4-SNAPSHOT, the test fails as per
issue#11 before it can get to this stage.

The test succeeds if you remove the third (copy) constructor.

import junit.framework.TestCase;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.Loader;
import org.yaml.snakeyaml.Dumper;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.Construct;
import org.yaml.snakeyaml.constructor.ConstructorException;

import java.io.*;
import java.util.*;

/**
** @author infinity0
*/
public class YamlMapTest extends TestCase {

    public void testYamlMap() throws IOException {
        Map<String, Object> data = new TreeMap<String, Object>();
        //data.put("key1", new Bean());
        //data.put("key2", new Bean());
        data.put("key3", new Custom("test"));
        data.put("key4", new Wrapper("test", new Custom("test")));

        Yaml yaml = new Yaml(new Loader(new ExtendedConstructor()),
                            new Dumper(new ExtendedRepresenter(), new DumperOptions()));
        File file = new File("beantest.yml");

        FileOutputStream os = new FileOutputStream(file);
        yaml.dump(data, new OutputStreamWriter(os));
        os.close();

        FileInputStream is = new FileInputStream(file);
        Object o = yaml.load(new InputStreamReader(is));
        is.close();

        assertTrue(o instanceof Map);
        Map m = (Map)o;
        //assertTrue(m.get("key1") instanceof Bean);
        // NOTE these tests fail in snakeYAML 1.2 and below, fixed in 1.3
        //assertTrue(m.get("key2") instanceof Bean);
        assertTrue(m.get("key3") instanceof Custom);
        assertTrue(m.get("key4") instanceof Wrapper);
    }
/*
    public static class Bean {
        private String a;
        public Bean() { a = ""; }
        public String getA() { return a; }
        public void setA(String s) { a = s; }

    }
*/
    public static class Wrapper {
        private String a;
        private Custom b;
        public Wrapper(String s, Custom bb) { a = s; b = bb; }
        public Wrapper() { }
        public String getA() { return a; }
        public void setA(String s) { a = s; }
        public Custom getB() { return b; }
        public void setB(Custom bb) { b = bb; }
    }

    public static class Custom {
        final private String str;
        public Custom(String s) {
            str = s;
        }
        public Custom(Integer i) {
            str = "";
        }
        /*public Custom(Custom c) {
            str = c.str;
        }*/
        public String toString() { return str; }
    }

    public static class ExtendedRepresenter extends Representer {
        public ExtendedRepresenter() {
            this.representers.put(Custom.class, new RepresentCustom());
        }

        private class RepresentCustom implements Represent {
            @Override public Node representData(Object data) {
                return representScalar("!Custom", ((Custom) data).toString());
            }
        }
    }

    public static class ExtendedConstructor extends Constructor {
        public ExtendedConstructor() {
            this.yamlConstructors.put("!Custom", new ConstructCustom());
        }

        private class ConstructCustom implements Construct {
            @Override public Object construct(Node node) {
                String str = (String) constructScalar((ScalarNode)node);
                return new Custom(str);
            }
            @Override public void construct2ndStep(Node node, Object object) { }
        }
    }

}

    [junit] Testcase: testYamlMap took 0.087 sec
    [junit]     Caused an ERROR
    [junit] null; Can't construct a java object for
tag:yaml.org,2002:plugins.Library.serial.YamlMapTest$Wrapper;
exception=org.yaml.snakeyaml.error.YAMLException:
java.lang.NoSuchMethodException:
plugins.Library.serial.YamlMapTest$Custom.<init>(plugins.Library.serial.YamlMapT
est$Custom)
    [junit] Can't construct a java object for
tag:yaml.org,2002:plugins.Library.serial.YamlMapTest$Wrapper;
exception=org.yaml.snakeyaml.error.YAMLException:
java.lang.NoSuchMethodException:
plugins.Library.serial.YamlMapTest$Custom.<init>(plugins.Library.serial.YamlMapT
est$Custom)
    [junit]  in "<reader>", line 1, column 6
    [junit] 
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constru
ctor.java:141)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.callConstructor(BaseConstructor.j
ava:117)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.callConstructor(Constructor.java:151)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.j
ava:107)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping2ndStep(BaseConst
ructor.java:189)
    [junit]     at
org.yaml.snakeyaml.constructor.SafeConstructor.constructMapping2ndStep(SafeConst
ructor.java:104)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping(BaseConstructor.
java:170)
    [junit]     at
org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlMap.construct(SafeCo
nstructor.java:423)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.callConstructor(BaseConstructor.j
ava:117)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.callConstructor(Constructor.java:151)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.j
ava:107)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor
.java:74)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.jav
a:68)
    [junit]     at org.yaml.snakeyaml.Loader.load(Loader.java:39)
    [junit]     at org.yaml.snakeyaml.Yaml.load(Yaml.java:164)
    [junit]     at
plugins.Library.serial.YamlMapTest.testYamlMap(YamlMapTest.java:47)
    [junit] Caused by: org.yaml.snakeyaml.error.YAMLException:
org.yaml.snakeyaml.error.YAMLException: java.lang.NoSuchMethodException:
plugins.Library.serial.YamlMapTest$Custom.<init>(plugins.Library.serial.YamlMapT
est$Custom)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.constructJavaBeanNode2ndStep(Construc
tor.java:388)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.constructJavaBeanNode(Constructor.jav
a:335)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.access$200(Constructor.java:33)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constru
ctor.java:108)
    [junit] Caused by: org.yaml.snakeyaml.error.YAMLException:
java.lang.NoSuchMethodException:
plugins.Library.serial.YamlMapTest$Custom.<init>(plugins.Library.serial.YamlMapT
est$Custom)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.constructJavaBeanScalarNode(Construct
or.java:296)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.callConstructor(Constructor.java:156)
    [junit]     at
org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.j
ava:107)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.constructJavaBeanNode2ndStep(Construc
tor.java:381)
    [junit] Caused by: java.lang.NoSuchMethodException:
plugins.Library.serial.YamlMapTest$Custom.<init>(plugins.Library.serial.YamlMapT
est$Custom)
    [junit]     at java.lang.Class.getConstructor0(Class.java:2723)
    [junit]     at java.lang.Class.getConstructor(Class.java:1674)
    [junit]     at
org.yaml.snakeyaml.constructor.Constructor.constructJavaBeanScalarNode(Construct
or.java:291)
    [junit] 

Original issue reported on code.google.com by infinity0x@gmail.com on 5 Aug 2009 at 9:14

GoogleCodeExporter commented 9 years ago
er.. sorry, i got muddled up. the test SUCCEEDS with the code given, but FAILs 
when
the copy constructor is removed.

the title of the bug is correct.

Original comment by infinity0x@gmail.com on 5 Aug 2009 at 9:16

GoogleCodeExporter commented 9 years ago
and again, as with issue#11, the test succeeds if the custom object is not part 
of a
java bean. (ie. if you comment out "key4" stuff)

Original comment by infinity0x@gmail.com on 5 Aug 2009 at 9:19

GoogleCodeExporter commented 9 years ago
is it fixed already ? 
Please check the patch with your test. I have uncommented everything but it 
works.

Original comment by aso...@gmail.com on 5 Aug 2009 at 1:11

Attachments:

GoogleCodeExporter commented 9 years ago
ah, sorry, the patch is wrong, you should keep the comments surrounding 

        /*public Custom(Custom c) {
            str = c.str;
        }*/

(or delete the whole thing) - i got a bit confused during the description

but anyway, i ran the test (with that constructor **removed**) on the latest 
hg, and
it passed (and failed on 1.3)

Original comment by infinity0x@gmail.com on 5 Aug 2009 at 2:03

GoogleCodeExporter commented 9 years ago
Indeed it fails on 1.3

I will mark the issue as fixed in 1.4

Original comment by py4fun@gmail.com on 5 Aug 2009 at 4:32

GoogleCodeExporter commented 9 years ago

Original comment by aso...@gmail.com on 6 Aug 2009 at 9:58

GoogleCodeExporter commented 9 years ago

Original comment by aso...@gmail.com on 6 Aug 2009 at 10:03