cuizhennan / snakeyaml

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

Load JavaBean with fields using custom constructors. #197

Closed GoogleCodeExporter closed 9 years ago

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

1. Use the Dice example: 
https://code.google.com/p/snakeyaml/source/browse/src/test/java/examples/DiceExa
mpleTest.java?name=v1.13
2. Make DiceConstructor extend Constructor instead SafeConstructor to be able 
to load JavaBeans.
3. Add a new JavaBean class like this and try to dump and load it using the 
implicit resolver: https://gist.github.com/Minecrell/d6d0509c61ae2ec15d90
4. Run the test

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

It will throw an exception because it does not use the custom Construct for the 
dice.
No single argument constructor found for class examples.Dice
Full exception: http://pastebin.com/zh7q7NrX

What version of SnakeYAML are you using? On what Java version?
1.13, Java 1.8.0_11 (I don't think the Java version affects this issue.)

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

In my point of view it should work on the same way like the test with the map. 
I have looked into the SnakeYAML source and have found the difference between 
them. 
Basicly the wrong constructor is chosen here: 
https://code.google.com/p/snakeyaml/source/browse/src/main/java/org/yaml/snakeya
ml/constructor/BaseConstructor.java?name=v1.13#191
This is because useClassConstructor will return true when loading the dumped 
map, but false when loading the JavaBean. 
The difference in the useClassConstructor method between both is that the type 
of the Node is Object when loading the map, but Dice when loading the JavaBean. 
Therefore this condition is true and it will return true and use the wrong 
constructor: 
https://code.google.com/p/snakeyaml/source/browse/src/main/java/org/yaml/snakeya
ml/nodes/Node.java#139

Is there anything I'm doing wrong or is that intended behaviour? (Why?)

Original issue reported on code.google.com by d...@minecrell.net on 21 Jul 2014 at 8:20

GoogleCodeExporter commented 9 years ago
What is the problem that you are trying to solve ? Can please show us some code 
which you expect to work with your change ?

Original comment by py4fun@gmail.com on 21 Jul 2014 at 3:08

GoogleCodeExporter commented 9 years ago
Well, I have not changed anything. Basicly I'm trying to dump (and load) a 
JavaBean (DiceBean in this example). I want to use a custom Constructor and 
Representer for one of the fields of the JavaBean (treasure here with the Dice 
class). If you run the test mentioned above then you will see that SnakeYAML 
will dump it correctly (like I want it to dump it) but it isn't able to load 
the dumped document again because it does not use the custom Constructor 
registered before. It should basicly work like the test with the map: 
https://code.google.com/p/snakeyaml/source/browse/src/test/java/examples/DiceExa
mpleTest.java?name=v1.13#93
The map works correctly, but loading the JavaBean throws an exception.

Original comment by d...@minecrell.net on 22 Jul 2014 at 6:42

GoogleCodeExporter commented 9 years ago
I think this is definitely a bug.

It works with a Map because type is not set for the Node (it's Object) and
{{{
 if (isResolved() && !Object.class.equals(type) && !tag.equals(Tag.NULL)) {
  return true;
 }
}}}
is not triggered. So Node.useClassConstructor returns false. As a result 
BaseConstructor.getConstructor() selects constructor based on the Tag (one set 
for !dice)

In case of JavaBean the type of treasure property resolved and 
Node.useClassConstructor returns true - BaseConstructor.getConstructor() 
selects constructor based on NodeType - Scalar and ScalarConstructor doesn't 
know how to deal with 10d10...

Original comment by alexande...@gmail.com on 22 Jul 2014 at 7:15

GoogleCodeExporter commented 9 years ago
Any idea how this could be fixed?

Original comment by d...@minecrell.net on 18 Aug 2014 at 7:26

GoogleCodeExporter commented 9 years ago
Checkout out latest changes and try, please.

I don't really like a solution I have chosen. But at the moment I don't see a 
better way with the current design.

Original comment by alexande...@gmail.com on 18 Aug 2014 at 12:59

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
That seems to be working in my test project I made. I will test it in my real 
project later but I think that fixed it. Thank you!

Original comment by d...@minecrell.net on 18 Aug 2014 at 1:18

GoogleCodeExporter commented 9 years ago
I declare this one fixed.

Original comment by alexande...@gmail.com on 29 Aug 2014 at 12:02