- attached empty.yaml
Empty yaml file must return null instead of throwing an exception when loading a JavaBean
Attempting to parse a (generated configuration) empty yaml file such as (see attachment)
using snakeyaml v1.17 and this method: org.yaml.snakeyaml.Yaml.loadAs(String, Class<C>)
throws a Constructor Exception:
org.yaml.snakeyaml.constructor.ConstructorException: Can't construct a java object for tag:yaml.org,2002:CLASSNAME; exception=No single argument constructor found for class CLASSNAME in 'string', line 4, column 1: ... ^
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:350) ~[snakeyaml-1.17.jar:na]
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:182) ~[snakeyaml-1.17.jar:na]
at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:141) ~[snakeyaml-1.17.jar:na]
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:127) ~[snakeyaml-1.17.jar:na]
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:450) ~[snakeyaml-1.17.jar:na]
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:427) ~[snakeyaml-1.17.jar:na]
at
... Caused by: org.yaml.snakeyaml.error.YAMLException: No single argument constructor found for class CLASSNAME at org.yaml.snakeyaml.constructor.Constructor$ConstructScalar.construct(Constructor.java:397) ~[snakeyaml-1.17.jar:na] at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:346) ~[snakeyaml-1.17.jar:na] ... 11 common frames omitted
However, a really empty file (without the --- ...) doesn't have this issue.
Comments (20)
-
reporter -
As you can see in the test your YAML document can be parsed without problems.
Can you please deliver a (failing) test ?
-
reporter In your test, you are setting the target bean/class type as String.class; which does have a constructor that could be called with the single argument "..." which is not correct. The result of that test should have been an empty string, not string == "..."
If you try to use a bean/class type that doesn't have a single string parameter constructor, do you get the expected results?
-
Have you seen this line:
assertEquals("", str);
The string is empty (as expected)
-
reporter Attached a failing test. It seems that the ctor(String) needs to exist even if it is not getting called with "..."
-
I added your test to the code base.
As you can see the constructor is NOT called with "..." (because there is no exception thrown)
-
reporter ok agreed, the presence of the ctor(String) or not is a red-herring. Are you able to reproduce the test failure on your branch? That test fails for me on v1.17 (I can't test higher versions at the moment... corporate environment = "paperwork")
-
If you help me to understand your complain:
However, a really empty file (without the --- ...) doesn't have this issue.
I can try to look further. For me there is no change with or without --- ...
I have updated the test. Please change it in such a way that I can understand the problem.
-
reporter The test is fine; using v1.17; this method emptyYamlTestAsObject() throws a org.yaml.snakeyaml.constructor.ConstructorException. If you can re-run this test on your build of 1.17 to confirm that I'm not going mad/doing something stupid; but can also show that the same test passes on v1.18, then we know that the issue has already been fixed.
-
- I take version 1.17
- Copy-and-paste the test from source
- Run the test - it is green.
Have you seen the test ? It does expect an exception.
-
reporter Ah no, I hadn't seen the update. But why do you expect this exception? Why should that throw an exception?
Also note that the emptyYamlTestAsObject test doesn't have the "..." footer.
-
reporter Or are you saying that v1.17 DOES expect the exception, and v1.18 does NOT expect the exception?
-
reporter btw, my point about a "really empty file (without the ---...) doesn't have this issue" is that this method is fine, and doesn't throw an exception:
@Test public void totallyEmptyYamlTestAsObject() { Yaml yaml = new Yaml(); TestObject obj = yaml.loadAs("", TestObject.class); Assert.assertNull(obj); }
Although whilst this method doesn't throw an unhandled exception; the behavior is different; I.e. returns null instead of returning an new uninitialized object (with all its attributes in their default state)
-
- The reason that we ask to provide a test is exactly to avoid this kind of ping-pong communication
- Both versions work the same way
- Your last comment finally helps me to identify 2 independent issues
- First issue is that the YAML documents which are resolved to an empty string cause different results (exception and null) - this is a bug
- Second issue is that you expect nothing to be an object while now SnakeYAML returns null - this is a feature request.
If you want to proceed I would recommend to close this issue and open another with exact description of your expectation (one by one, or just the one which is important for you).
-
I see now where it fails (where it does not throw an exception but it should).
-
reporter Thanks Andrey; and sorry for the back-and-forth comms.
Can you confirm what the v1.8 (and head going forwards) behavior is for the empty (with header/footer) yaml parsing to a complex object? Should this throw a constructor exception or not (I assume not). And that this issue was fixed somewhere along the line between 1.7 (throws exception) and 1.8 (no longer throws exception). And with v >=1.8 the result will be to construct a new object of the correct type, and leave it in is default/initializer state.
The issue with a truly empty file returning null vs an unpopulated new object would represent a behavioural backwards compatibility breaking change. I don't especially need this behavior to change, and so whilst conceptually I agree that this is a bug and they should produce the same results; I would understand the rationale for treading cautiously here. I'm happy to re-raise this as a separate issue/feature request if you would like, but it is not a change that I would especially be pushing for.
-
Thank you. Finally the bug is identified. Regardless how an empty document is defined it should return null. The fix is coming...
-
- changed status to resolved
Fix issue 375: empty yaml file must return null instead of throwing an exception when loading a JavaBean
→ <<cset 3ec80bf7bbbc>>
-
- Versions 1.7 and 1.8 are far too old. No comments.
- If you mean 1.17 and 1.18 then both have same bug - sometimes an empty YAML document throws an exception instead of returning null
- It is just fixed and from version 1.19 on it should always return null for any empty document
-
It will be delivered in version 1.19 (https://bitbucket.org/asomov/snakeyaml/wiki/Changes)
Thank you.
- Log in to comment
attached example emtpy.yaml as it got munged by jira markup in description