Can I link non j3o files to scene using AssetLinkNode?

Hi

I am using AssetLinkNode to export my scene to j3o.
When I am linking a j3o ModelKey it export/loads fine but when I am linking xbuf ModelKey I can export the scene but I get following error when loading it.

java.lang.OutOfMemoryError: Java heap space
	at com.jme3.export.binary.BinaryImporter.readString(BinaryImporter.java:290) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:181) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:125) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:109) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.scene.AssetLinkNode.read(AssetLinkNode.java:177) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:342) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:483) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:471) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:587) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.scene.Node.read(Node.java:744) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:342) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:483) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:471) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:587) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.scene.Node.read(Node.java:744) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:342) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:483) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:471) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:587) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.scene.Node.read(Node.java:744) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:342) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:242) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:125) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:109) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:259) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:373) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:416) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:420) ~[jme3-core-3.2.0-SNAPSHOT.jar:3.2-6188]
	at com.overthemoon.core.state.editor.EditorState$LoadCommand$1.execute(EditorState.java:756) ~[editor-client-0.1-SNAPSHOT.jar:?]
	at com.overthemoon.core.state.editor.EditorState$LoadCommand$1.execute(EditorState.java:746) ~[editor-client-0.1-SNAPSHOT.jar:?]
	at com.simsilica.lemur.core.CommandMap.runCommands(CommandMap.java:61) ~[lemur-1.10.1.jar:?]
	at com.simsilica.lemur.Button.runClick(Button.java:333) ~[lemur-1.10.1.jar:?]

I have already registered Xbuf loader to AssetManager.

So want to get sure if linking a non j3o extension is possible through AssetLinkNode ?

Thanks

Created a simple test case :

public class TestXbufAssetLinkNode extends SimpleApplication {

    public void simpleInitApp() {

        assetManager.registerLoader(XbufLoader.class, "xbuf");

        //Step 1: (works fine)
        //createScene();
        
        //Step 2: (throws exception)
        loadScene();
        
        
        
        /**
         * A white, directional light source
         */
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
        sun.setColor(ColorRGBA.White);
        rootNode.addLight(sun);

    }

    private void createScene() {
        //Create scene
        AssetLinkNode wall = new AssetLinkNode("wall", new ModelKey("wall.xbuf"));
        wall.attachLinkedChildren(assetManager);
        
        //Save scene
        final BinaryExporter exp = BinaryExporter.getInstance();

        final File file = new File("/media/idea/My Passport/Java/jME_NB-PW-11-6-2015/OverTheMoon/assets/Models/modular-room-props/wall-linked.j3o");

        try (FileOutputStream out = new FileOutputStream(file)) {
            
            file.createNewFile();
            exp.save(wall, out);
        
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        rootNode.attachChild(wall);
        
    }

    private void loadScene() {
        //Load generated scene
        Spatial wall = assetManager.loadModel(new ModelKey("wall-linked.j3o"));
        rootNode.attachChild(wall);
    }
    
    
     @Override
    public void simpleUpdate(float tpf) {

    }

    public static void main(String[] args) {
        TestXbufAssetLinkNode main = new TestXbufAssetLinkNode();
        main.start();
    }

}

output :

java.lang.OutOfMemoryError: Java heap space
	at com.jme3.export.binary.BinaryImporter.readString(BinaryImporter.java:290)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:181)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:125)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:109)
	at com.jme3.scene.AssetLinkNode.read(AssetLinkNode.java:177)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:342)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:242)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:125)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:109)
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:259)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:373)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:416)
	at com.overthemoon.main.TestXbufAssetLinkNode.loadScene(TestXbufAssetLinkNode.java:96)
	at com.overthemoon.main.TestXbufAssetLinkNode.simpleInitApp(TestXbufAssetLinkNode.java:55)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:220)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:211)
	at java.lang.Thread.run(Thread.java:745)

Note :
In step 1

 //Create scene
        AssetLinkNode wall = new AssetLinkNode("wall", new ModelKey("wall.xbuf")); 
        wall.attachLinkedChildren(assetManager);

If I link a .j3o file (instead of .xbuf) everything will work fine when loading the scene (step 2).

Looks like a bug.
Any thoughts ?

Have you tried to increase the heap memory actually? Maybe the xbuf Import just uses more ram since it cant be directly loaded into the Scene?

@Darkchaos thanks for replying

Yes I tried to increase it, but no difference, the error shows up.
The file size is very small (1 KB), it is just a simple cube model.
When I directly load it (without using AssetLinkedNode) it works fine.

I do not know how AssetManager is working internally, but I guess ( most likely sure :wink:) when loading the scene it tries to load it with j3o loader instead of using Xbuf loader. Because when I am commenting this line when loading the scene (step 2)

//assetManager.registerLoader(XbufLoader.class, "xbuf");

It does not throw any exception regarding Xbuf loader is not registered, which makes me sure that it does not use Xbuf loader at all.

It’s possible that the AssetLinkNode only works with j3o since JME is designed to only deploy with j3o support.

Yes, I guess.
I just wanted to get sure about it. :slight_smile: