Saving/Loading a normal jme node crashes

I just wanted to test how saving games/levels/nodes work and got the following error:

[java]
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.jme3.material.Material.read(Material.java:1177)
at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:340)
at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:457)
at com.jme3.scene.Geometry.read(Geometry.java:564)
at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:340)
at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:483)
at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:471)
at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:587)
at com.jme3.scene.Node.read(Node.java:599)
at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:340)
at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:242)
at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:125)
at jme3tools.savegame.SaveGame.loadGame(SaveGame.java:184)
at jme3tools.savegame.SaveGame.loadGame(SaveGame.java:128)
at exampleApps.JnRApp.testSaving(JnRApp.java:93)
[/java]

Here is the relevant code which crashes:

[java]
@Override
public void simpleInitApp() {

	testSaving(newCoordinateAxes(new Vector3f()));
	...

public Node newCoordinateAxes(Vector3f pos) {
	Node n = new Node();

	Arrow arrow = new Arrow(Vector3f.UNIT_X);
	arrow.setLineWidth(4); // make arrow thicker
	putShape(arrow, ColorRGBA.Red, n).setLocalTranslation(pos);

	arrow = new Arrow(Vector3f.UNIT_Y);
	arrow.setLineWidth(4); // make arrow thicker
	putShape(arrow, ColorRGBA.Green, n).setLocalTranslation(pos);

	arrow = new Arrow(Vector3f.UNIT_Z);
	arrow.setLineWidth(4); // make arrow thicker
	putShape(arrow, ColorRGBA.Blue, n).setLocalTranslation(pos);
	return n;
}

private void testSaving(Savable s) {
	SaveGame.saveGame("test/test", "test", s);
	Savable s2 = SaveGame.loadGame("test/test", "test");
}

[/java]

what am i doing wrong, do I have to initialize something else before the loading works? The file is created on the disc (and its not empty) so I assume saving is correctly…

im.getAssetManager() must be null otherwise the exception would not be thrown…

Ok if I change it to

[java] private void testSaving(Savable s) {
SaveGame.saveGame(“test/test”, “test”, s);
Savable s2 = SaveGame.loadGame(“test/test”, “test”, assetManager);
}[/java]

the error does not happen so maybe this is a jme bug and the assetmanager is not initialized in the SaveGame class?

Needing assetManager depends on what you are loading. If you use a method that does not pass in the assetManager, you can’t load objects that use assetManager for loading (ie. models with material/textures).

[java]
/**
* Loads a savable that has been saved on this system with saveGame() before.
* @param gamePath A unique path for this game, e.g. com/mycompany/mygame
* @param dataName A unique name for this savegame, e.g. “save_001”
* @param manager Link to an AssetManager if required for loading the data (e.g. models with textures)
* @return The savable that was saved or null if none was found
*/
public static Savable loadGame(String gamePath, String dataName, AssetManager manager) {
return loadGame(gamePath, dataName, manager, JmeSystem.StorageFolderType.External);
}
[/java]

Ok maybe the other method without the assetmanager should be deprecated then? I mean the assetmanager is always available for the developer so it is more confusing than useful to provide the load method where the assetmanager then will be null

Another thing I came along is the BitmapText which does not have a default constructor so if I try to save and load it I get

[java]Jun 20, 2013 3:24:07 PM com.jme3.export.SavableClassUtil fromName
SEVERE: Could not access constructor of class ‘com.jme3.font.BitmapText’!
Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup.
Jun 20, 2013 3:24:07 PM class com.jme3.export.binary.BinaryImporter readObject(int id)
SEVERE: Exception
java.lang.InstantiationException: com.jme3.font.BitmapText
at java.lang.Class.newInstance0(Class.java:359)
at java.lang.Class.newInstance(Class.java:327)
at com.jme3.export.SavableClassUtil.fromName(SavableClassUtil.java:171)[/java]

There is also no custom save or load behavior implemented as well (e.g. the current text), maybe this is just missing yet or am I doing something wrong?

Related to the assetManager item, we use loadGame / saveGame to save data not related to the visual objects like game state, score, level, etc… These are simply nodes with userData. That is a case where you can save/load without any knowledge of the assetManager.