ldh0826 / snakeyaml

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

snakeyaml should try harder when matching constructor signatures #181

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

1. public class Foo {
       public final List<String> bars;
       public Foo(List<String> bars) {
          this.bars = bars;
       }
   }

2 YAML:   !!Foo ['a','b','c'] # sequence of scalars for constructor

What is the expected output? What do you see instead?

  SnakeYAML can't locate the constructor with a signature taking an ArrayList.  Indeed, one does not exist.
  However, it is ignoring the constructor with a signature for a wider type.

  This is similarly an issue for primitive types declared in constructors.  SnakeYAML treats interger literals in YAML as if they map to java.lang.Integer and won't match a constructor which uses javal.lang.Integer.TYPE (aka. 'int').

What version of SnakeYAML are you using? On what Java version?

   1.14-SNAPSHPOT on JDK 1.7_u25

Please provide any additional information below. (Often a failing test is
the best way to describe the problem.)

Creating objects using their constructor is important to me, because I'm 
writing multi-threaded code, and the fastest path to type-safety is to make the 
class immutable using 'final' fields (which in turn requires the constructor).  
I'm very glad I can do this at all with SnakeYAML, when so many other 
serialization libraries fail to offer it.

I really would prefer that SnakeYAML not impose any further design constraints 
on me regarding the design of the constructor.  The constructor is part of the 
public contract of the class, and I don't want to commit to 
unnecessarily-narrow types just so I can express the object concisely in a 
human-readable format via YAML.  Further, I'm not always in a position to 
influence the design of a constructor.

I am using YAML in my app as a 'configuration language'.

PS:  Thank you for creating SnakeYAML :-)   It made my day.

Original issue reported on code.google.com by david.bu...@machaira.com.au on 24 Sep 2013 at 2:39

GoogleCodeExporter commented 8 years ago
Well, how do you expect to distinguish 3 constructors for the proposed syntax:

!!Foo ['a','b','c']

public class Foo {
       public final List<String> bars;
       public Foo(List<String> bars) { //1st
          this.bars = bars;
          //do some stuff
       }
       public Foo(String... args) { // 2nd
          this.bars = bars;
          //do some other stuff
       }
       public Foo(String s1, String s2, String s3) { //3rd
          this.bars = bars;
          //do yet another stuff
       }
   }

What about this ?

public class Foo extends List<String>

Please be aware that SnakeYAML has some restrictions on the object construction 
because it tries to stay general. If you write your own Constructor (sorry for 
the confusing terminology), you can create anything you like. You are only 
restricted by your imagination...

Original comment by py4fun@gmail.com on 24 Sep 2013 at 8:42

GoogleCodeExporter commented 8 years ago
My apologies for a faulty issue description.  I *meant* to say:

  YAML:  !!Foo [['a','b','c']]

Should find a constructor signature like:

  Foo(List list)

But at the moment, it will only find:

  Foo(ArrayList list)

And for primitives: 

  YAML:   !!Bar [1]

Should find constructor signature:

  Bar(int i)

But at the moment it only finds:

  Bar(Integer i)

I observed a similar 'could not find constructor' issue for 
boolean/java.lang.Boolean as well.

I agree that it isn't snakeyaml's place to try and second-guess the signatures 
and marshall String,String,String to List<String>.  My bad, sorry.

Original comment by david.bu...@machaira.com.au on 24 Sep 2013 at 11:41

GoogleCodeExporter commented 8 years ago
would it be possible to get failing TestCase ?

Original comment by alexande...@gmail.com on 25 Sep 2013 at 6:02

GoogleCodeExporter commented 8 years ago
btw, are those constructors public? (I mean in your particular case - int, 
boolean, ...)
Seems like we search only for public constructors at the moment. Ant tests 
connected to immutable objects do use primitive constructors. For example 
Color(int,int,int)

2py4fun : should we actually check all af them?

Original comment by alexande...@gmail.com on 25 Sep 2013 at 6:13

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Sorry, my problem is an old snakeyaml on the classpath, thanks to it being 
bundled with TestNG.  Isolating for just 1.14-SNAPSHOT it works just as it 
ought to.  Sorry about the bogus report.  Please close this issue as 'cannot 
reproduce'.

Original comment by david.bu...@machaira.com.au on 25 Sep 2013 at 7:45

GoogleCodeExporter commented 8 years ago
2 alexander.maslov:
we may try to check them all (if you know how to do it without a lot of 
overhead)

Original comment by py4fun@gmail.com on 25 Sep 2013 at 7:54