Support for generic types when serializing and deserializing?
Currently SnakeYaml only support beans deserialization via:
public <T> T loadAs(String yaml, Class<T> type)
This make near impossible to write some own library for some serialization/deserialization using snakeyaml, especially if data isn't made by us and does not contain type tags in it.
It would be awesome to be able to use methods like this:
public <T> T loadAs(String yaml, Type type)
public String dumpAs(Object object, Type type) // will not include type tags for known types that can be read from generic
Just like in GSON library.
As I see you often want to see some test cases describing issue, I attached one, but ofc code will not compile, as this is request for new methods that will support that features. Test requires GSON, as I didn't want to include whole TypeToken<T> API.
Comments (11)
-
-
reporter Sorry, I do not have time in this month. Any chance that you will do it later? If not, then maybe I will find some time in next months, but just not in this one.
-
Issue
#388was marked as a duplicate of this issue. -
Same issue for me. My yaml document root is a list of TestCase:
- input: ["val1","val2"] expected: ["val3","val4"] - input: ["val5","val6"] expected: ["val7","val8"]
TestCase:
public class TestCase { public List<String> input; public List<String> expected; }
I try to use SnakeYaml to deserialize it as a List<TestCase>:
List<TestCase> tests = new Yaml().load(is);
Unfortunately I get a List of HashMap instead, I didn't find any way in SnakeYaml to provide the List generic type.
With jackson, when deserializing json, we can use a TypeRefence to do this, example with jackson and the same document in json:
List<TestCase> tests = mapper.readValue(is, new TypeReference<List<TestCase>>(){});
What I get is effectively a List<TestCase>!
I found out a little hack to achieve this with SnakeYaml, I try to deserialize to a typed array first, then convert the array into a List. Since arrays are statically typed it works !
TestCase[] testsArray = new Yaml().loadAs(is, TestCase[].class); List<TestCase> tests = Arrays.asList(testArray);
I get a List<TestCase> like I wanted, but it looks very hacky and it would be great if SnakeYaml could natively support a mecanism like Jackson (or Gson)
Thanks !
-
@Anthony Foulfoin this issue may be fixed by PR #5
-
The problem I found was related to this problem, but I encountered a very strange situation. The YAML I tested here can be deserialized normally in
snakeyaml
1.16
version , but the generic information is lost insnakeyaml
1.19-1.30
version .Take the following program as an example, it works fine on snakeyaml
1.16-1.18
, but in1.19-1.30
version the generic information is lost, causingClassCastException
.public enum ExecuteProcessConstants { EXECUTE_ID, EXECUTE_STATUS_START, EXECUTE_STATUS_DONE } @NoArgsConstructor @AllArgsConstructor @Data public class YamlExecuteProcessUnit { private String unitID; private ExecuteProcessConstants status; } @NoArgsConstructor @AllArgsConstructor @Data public class YamlExecuteProcessContext { private String executionID; private String schemaName; private String username; private String hostname; private String sql; private Collection<YamlExecuteProcessUnit> unitStatuses; private Long startTimeMillis; } public class JunitTest { @Test public void snakeYamlTest3() { String marshal = "unitStatuses: !!set\n" + " ? status: EXECUTE_STATUS_DONE\n" + " unitID: '159917166'\n" + " : null\n"; YamlExecuteProcessContext unmarshal = new Yaml(new Constructor(YamlExecuteProcessContext.class)).loadAs(marshal,YamlExecuteProcessContext.class); for (YamlExecuteProcessUnit unit : unmarshal.getUnitStatuses()) { System.out.println("test problem in class ---------" + unit.getClass().getName()); if (unit.getStatus() != ExecuteProcessConstants.EXECUTE_STATUS_DONE) { return; } } } }
The discovery of this issue is related to https://github.com/apache/shardingsphere/pull/15260 , and a separate test case is linked to snakeyaml-update-test/JunitTest.java at master · linghengqian/snakeyaml-update-test (github.com) .
Hope some friends can tell me the reason, I didn't see enough information in the update log of snakeyaml1.19
to support the problem.
-
this is a nice one 6 years nobody reported it. I have a fix for this.
Not sure it is related to this issue, but let’s see. I need to write maybe couple of tests to see what kind of situation it fixes.
At least no current tests are failing. And your test is also passing. -
-
assigned issue to
-
assigned issue to
-
change how we set detected type to JavaBean Collection property item
fixes regression introduced in 1.19 when generics information is lost for JavaBean Collection property.
refs issue #387
→ <<cset 9d7dbb869ba9>>
-
change how we set detected type to JavaBean Collection property item
fixes regression introduced in 1.19 when generics information is lost for JavaBean Collection property.
refs issue #387
→ <<cset 6385279ecb0b>>
-
- thank you very much! I think this issue can be closed.
- Log in to comment
If you deliver the pull request with the implementation this month, we can include it in the coming release in August.