[SOLVED]Clone exception

Trying to clone a node to explore cloning.

One of the controls is just a class extending BetterCharacterControl implementing ActionListener.

java.lang.ClassCastException: Cannot cast com.jme3.bullet.control.BetterCharacterControl to mygame.controls.PCControl
	at java.lang.Class.cast(Class.java:3369)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:276)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
	at com.jme3.util.clone.ListCloneFunction.cloneFields(ListCloneFunction.java:66)
	at com.jme3.util.clone.ListCloneFunction.cloneFields(ListCloneFunction.java:43)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:228)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
	at com.jme3.scene.Spatial.cloneFields(Spatial.java:1506)
	at com.jme3.scene.Node.cloneFields(Node.java:723)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:255)
	at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
	at com.jme3.scene.Spatial.clone(Spatial.java:1361)
	at com.jme3.scene.Node.clone(Node.java:682)
	at com.jme3.scene.Node.clone(Node.java:62)
	at com.jme3.scene.Spatial.clone(Spatial.java:1449)
	at mygame.appstates.PCState.cloneSpatialControl(PCState.java:122)
	at mygame.appstates.PCState.onEnable(PCState.java:106)
	at com.jme3.app.state.BaseAppState.initialize(BaseAppState.java:127)
	at com.jme3.app.state.AppStateManager.initializePending(AppStateManager.java:251)
	at com.jme3.app.state.AppStateManager.update(AppStateManager.java:281)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:236)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
	at java.lang.Thread.run(Thread.java:745)

BUILD SUCCESSFUL (total time: 6 seconds)

I have tried using Cloner and just cloning the Node directly like so,

    private void cloneCheck() {
        Node newNode = charNode.clone(false);
        for (int i = 0; i < newNode.getNumControls(); i++) {
            System.out.println("Cloned Control" + newNode.getControl(i));

Am I doing something wrong here?

Try making a testcase for it (start from test jme app, do a node.clone etc.) then see if that breaks. If it does you can post it here for reference.

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.input.controls.ActionListener;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;

 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 * @author normenhansen
public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();

    public void simpleInitApp() {
        Node charNode = new Node("testControlNode");
        charNode.addControl(new BCControl(1, 1, 1));

    private void cloneCheck(Node node) {
        Node newNode = node.clone(false);
    public class BCControl extends BetterCharacterControl implements ActionListener {

        public BCControl(float radius, float height, float mass) {
            super(radius, height, mass);

        public void update(float tpf) {


        public void onAction(String name, boolean isPressed, float tpf) {


    public void simpleUpdate(float tpf) {
        //TODO: add update code

    public void simpleRender(RenderManager rm) {
        //TODO: add render code


I am calling the clone from an AppState onEnable() in the other app BTW.

In order for cloning to work, you need to tell JME how to clone a BCControl. One way to do this would be to
define a jmeClone() method for BCControl, something like this:

        public BCControl jmeClone() {
            try {
                BCControl clone = (BCControl) super.clone();
                return clone;
            } catch (CloneNotSupportedException exception) {
                throw new RuntimeException(exception);
1 Like

That did it. Thank you.

1 Like