Hello. So I'm completely new to both yaml and serialization. I think I'm jumping into the deep end with a lot of this and I haven't found very many resources explaining things, so I'm a bit lost. Anyway, I ran into trouble with serializing an instance of JBox2D's Body. This error happens when I attempt to serialize:
Exception in thread "main" org.yaml.snakeyaml.error.YAMLException: No JavaBean properties found in org.jbox2d.dynamics.FixtureProxy
at org.yaml.snakeyaml.introspector.PropertyUtils.getPropertiesMap(PropertyUtils.java:87)
at org.yaml.snakeyaml.introspector.PropertyUtils.createPropertySet(PropertyUtils.java:110)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperties(PropertyUtils.java:102)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperties(PropertyUtils.java:94)
at org.yaml.snakeyaml.representer.Representer.getProperties(Representer.java:238)
at org.yaml.snakeyaml.representer.Representer$RepresentJavaBean.representData(Representer.java:49)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepresenter.java:109)
at org.yaml.snakeyaml.representer.BaseRepresenter.representSequence(BaseRepresenter.java:137)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentArray.representData(SafeRepresenter.java:206)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepresenter.java:95)
at org.yaml.snakeyaml.representer.Representer.representJavaBeanProperty(Representer.java:125)
at org.yaml.snakeyaml.representer.Representer.representJavaBean(Representer.java:83)
at org.yaml.snakeyaml.representer.Representer$RepresentJavaBean.representData(Representer.java:49)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepresenter.java:109)
at org.yaml.snakeyaml.representer.Representer.representJavaBeanProperty(Representer.java:125)
at org.yaml.snakeyaml.representer.Representer.representJavaBean(Representer.java:83)
at org.yaml.snakeyaml.representer.Representer$RepresentJavaBean.representData(Representer.java:49)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepresenter.java:109)
at org.yaml.snakeyaml.representer.BaseRepresenter.represent(BaseRepresenter.java:65)
at org.yaml.snakeyaml.Yaml.dumpAll(Yaml.java:271)
at org.yaml.snakeyaml.Yaml.dumpAll(Yaml.java:262)
at org.yaml.snakeyaml.Yaml.dumpAll(Yaml.java:234)
at org.yaml.snakeyaml.Yaml.dump(Yaml.java:209)
Here's the source for Body:
https://github.com/jbox2d/jbox2d/blob/master/jbox2d-library/src/main/java/org/jbox2d/dynamics/Body.javaLooking at the source for Body I assumed it would be impossible to serialize some of its fields. m_sweep, m_world, m_prev, m_next, and m_userData can all be decided at runtime and so don't need to be serialized. The World and Body fields in particular, I assume, are problematic because of circular referencing. World contains a reference to the Body we're trying to serialize which contains the World, etc. I went ahead and tried to make a custom representer:
public class BodyRepresenter extends Representer
{
public BodyRepresenter()
{
this.representers.put(Body.class, new RepresentBody());
}
private class RepresentBody implements Represent
{
@Override
public Node representData(Object o)
{
Body body = (Body)o;
String newline = " ";
String value = "";
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
options.setWidth(200);
Yaml yaml = new Yaml(new FixtureRepresenter(), options);
value += "m_type: " + body.m_type;
value += newline + "m_flags: " + body.m_flags;
value += newline + "m_islandIndex: " + body.m_islandIndex;
value += newline + "m_xf: " + yaml.dump(body.m_xf);
value += "m_linearVelocity: " + yaml.dump(body.m_linearVelocity);
value += "m_angularVelocity: " + body.m_angularVelocity;
value += newline + "m_force: " + yaml.dump(body.m_force);
value += "m_torque: " + body.m_torque;
value += newline + "m_linearDamping: " + body.m_linearDamping;
value += newline + "m_angularDamping: " + body.m_angularDamping;
value += newline + "m_gravityScale: " + body.m_gravityScale;
value += newline + "m_sleepTime: " + body.m_sleepTime;
value += newline + "m_fixtureList: " + yaml.dump(body.m_fixtureList);
System.out.println(value);
return representScalar(new Tag("!!org.jbox2d.dynamics.Body"), value);
}
}
}
And also for Fixture.
Source is here:
https://github.com/jbox2d/jbox2d/blob/master/jbox2d-library/src/main/java/org/jbox2d/dynamics/Fixture.javapublic class FixtureRepresenter extends Representer
{
public FixtureRepresenter()
{
this.representers.put(Fixture.class, new RepresentFixture());
}
private class RepresentFixture implements Represent
{
@Override
public Node representData(Object o)
{
Fixture fixture = (Fixture)o;
String newline = " ";
String value = "";
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
options.setWidth(200);
Yaml yaml = new Yaml(options);
value += "m_density: " + fixture.m_density;
value += newline + "m_shape: " + yaml.dump(fixture.m_shape);
value += "m_friction: " + fixture.m_friction;
value += newline + "m_restitution: " + fixture.m_restitution;
value += newline + "m_isSensor: " + fixture.m_isSensor;
return representScalar(new Tag("!!org.jbox2d.dynamics.Fixture"), value);
}
}
}
Now here's the problem. When I dump using these representers, I get this unreadable mess:
!!org.jbox2d.dynamics.Body "m_type: DYNAMIC m_flags: 38 m_islandIndex: 0 m_xf: !!org.jbox2d.common.Transform\
\ {p: {x: 12.5, y: 12.5}, q: {c: 1.0, s: 0.0}}\nm_linearVelocity: !!org.jbox2d.common.Vec2\
\ {x: 0.0, y: 0.0}\nm_angularVelocity: 0.0 m_force: !!org.jbox2d.common.Vec2 {x:\
\ 0.0, y: 0.0}\nm_torque: 0.0 m_linearDamping: 3.0 m_angularDamping: 10.0 m_gravityScale:\
\ 1.0 m_sleepTime: 0.0 m_fixtureList: !!org.jbox2d.dynamics.Fixture 'm_density:\
\ 1.0 m_shape: !!org.jbox2d.collision.shapes.CircleShape {m_p: {x: 0.0, y: 0.0},\
\ m_radius: 0.38, m_type: CIRCLE, radius: 0.38}\n\n m_friction: 0.2 m_restitution:\
\ 1.0 m_isSensor: false'\n"
If I replace newline with "\n" then I get pretty much the same thing with more \n's strewn around. I must be missing something obvious with how the representScalar() method works because I'm sure that's where everything goes wrong.