Null Pointer Exception in main class

Hello, I have recently downloaded jMonkeyEngine and I have stumbled into a slight problem that I cannot solve. My player class seems to cause it when I attach it to the rootnode, it is probably a rookie mistake and I would appreciate some help. Here is the code for the 2 classes starting with my player class.

player.java
[java]
package com.destroyerGames.aberration.characters;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.;
import com.jme3.input.controls.
;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

/**
@author Destroyer Games
/
public class Player {
/
*
creates instances of classes to use in the code.
*/
private FlyByCamera flyCam;
private CharacterControl player;
private InputManager inputManager;
private SimpleApplication application;
private Node rootNode;
private CameraNode camNode;

/**
 The states of the player. Defined by strings, and represented to the game
 as decimal data values.
 */
private int state;
private static final int STATE_ALIVE = 0;
private static final int STATE_DEAD = 1;
private static final int STATE_ATTACKING = 2;
private static final int STATE_PUSHED = 3;
private static final int STATE_ATTACKED = 4;
private static final int STATE_SWINGING_SWORD = 5;
private static final int STATE_FIRING_SEMIAUTOMATIC_GUN = 6;
private static final int STATE_FIRING_AUTOMATIC_GUN = 7;
private static final int STATE_FIRING_BOW = 8;
private static final int STATE_RELOADING = 9;
private static final int STATE_WALKING = 10;
/**
 An idTag is a special identifier for a class that specifies which package
 The UpdateManager will put the class in. In this case the 
 com.destroyerGames.aberration.characters' special idTag is the number 2.
 */
public static final int idTag = 2;
/**
 The actions that the player will take. To be mapped with a certain key.
 */
public boolean Left = false, Right = false, Forward = false,
        Backward = false, Jump = false, Attack = false, Block = false,
        Sneak = false, Action = false, Reload = false;

/**
 Strings
 */
public String name;

/**
 Makes it compatible with SimpleApplication
 */
public Player(SimpleApplication application, String name) {
    this.application = application;
}

/**
 Pulls everything together
 */
public void initPlayer() {
    fpCamera();
    receiveDigitalInput();
    receiveAnalogInput();
    
}
/**
 Configures the player
 */
public void playerConfig() {
    player.setUpAxis(1);
    player.setMaxSlope(2.0f);
    player.setGravity(2.5f);
}
/**
 Set up the first-person camera
 */
public void fpCamera() {
    flyCam.setEnabled(true);
    flyCam.setMoveSpeed(2);
    application.getRootNode().attachChild(camNode);
}
/**
 Set up the digital, on button-press, actions
 */
public void receiveDigitalInput() {
    inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addMapping("Action", new KeyTrigger(KeyInput.KEY_E));
    inputManager.addMapping("Reload", new KeyTrigger(KeyInput.KEY_R));
    inputManager.addListener(action, new String[] {"Jump"});
    inputManager.addListener(action, new String[] {"Action"});
    inputManager.addListener(action, new String[] {"Reload"});
}
/**
 Receives the analog, held down button, actions
 */
public void receiveAnalogInput() {
    inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("Backward", new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("AutoFire", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    inputManager.addMapping("Aim", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
    inputManager.addListener(analog, new String[] {"Forward"});
    inputManager.addListener(analog, new String[] {"Backward"});
    inputManager.addListener(analog, new String[] {"Left"});
    inputManager.addListener(analog, new String[] {"Right"});
    inputManager.addListener(analog, new String[] {"AutoFire"});
    inputManager.addListener(analog, new String[] {"Aim"});
}
private ActionListener action = new ActionListener() {
   public void onAction(String name, boolean isPressed, float tpf) {
       if (name.equals("Reload")) {
           state = STATE_RELOADING;
       }
   }
};
private AnalogListener analog = new AnalogListener() {
    public void onAnalog(String name, float value, float tpf) {
        if (name.equals("Forward")) {
            Forward = true;
            player.setWalkDirection(new Vector3f(0f,0f,-2f));
            state = STATE_WALKING;
        }
        else {
            Forward = false;
            player.setWalkDirection(new Vector3f(0f,0f,0f));
        }
        if (name.equals("Backward")) {
            Backward = true;
            player.setWalkDirection(new Vector3f(0f,0f,2f));
            state = STATE_WALKING;
        }
        else {
            Backward = false;
            player.setWalkDirection(new Vector3f(0f,0f,0f));
        }
        if (name.equals("Left")) {
            Left = true;
            player.setWalkDirection(new Vector3f(-2f, 0f, 0f));
            state = STATE_WALKING;
        }
        else {
            Left = false;
            player.setWalkDirection(new Vector3f(0f, 0f, 0f));
        }
        if (name.equals("Right")) {
            Right = true;
            player.setWalkDirection(new Vector3f(2f, 0f, 0f));
            state = STATE_WALKING;
        }
        else {
            Right = false;
            player.setWalkDirection(new Vector3f(0f, 0f, 0f));
        }
        if (name.equals("Forward") && name.equals("Left")) {
            player.setWalkDirection(new Vector3f (-2f, 0f, -2f));
            state = STATE_WALKING;
        }
        else {
            player.setWalkDirection(new Vector3f(0f, 0f, 0f));
        }
        if (name.equals("Forward") && name.equals("Right")) {
            player.setWalkDirection(new Vector3f(2f, 0f, -2f));
            state = STATE_WALKING;
        }
        else {
            player.setWalkDirection(new Vector3f(0f, 0f, 0f));
        }
        if (name.equals("Backward") && name.equals("Left")) {
            player.setWalkDirection(new Vector3f(-2f, 0f, 2f));
            state = STATE_WALKING;
        }
        else {
            player.setWalkDirection(new Vector3f(0f, 0f, 0f));
        }
        if (name.equals("Backward") && name.equals("Right")) {
            player.setWalkDirection(new Vector3f(2f, 0f, 2f));
            state = STATE_WALKING;
        }
    }
};

}

[/java]

Here is the main class:

main.java
[java]
package com.destroyerGames.aberration;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.destroyerGames.aberration.graphics.OpenWorldLoader;
import com.jme3.scene.Spatial;
import com.destroyerGames.aberration.characters.Player;
import com.jme3.scene.CameraNode;

public class Main extends SimpleApplication {
private OpenWorldLoader openWorld;
private Player player;

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

@Override
public void simpleInitApp() {
    Spatial scene = assetManager.loadModel("Scenes/somePlace.j3o");
    
    player.initPlayer();
    
    rootNode.attachChild(scene);
}

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

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

}
[/java]

The following code gives me this stack trace:
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.destroyerGames.aberration.Main.simpleInitApp(Main.java:29)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:722)

again help would be appreciated and sorry if my programming is hard to read. I am also sorry if this exact question has been asked before. Thanks in advance. Also, are there any books out there to help people with development in jMonkeyEngine to help me avoid problems of this nature again.

I cannot see that you are creating a new instance of the Player class anywhere… and if you do, then it’s going to blow up anyway because you have uninitialized variables in the Player class.

Do you have prior experience of programming in java?

I’ve read a few books but otherwise no, i do not have much experience with java. I am mainly learning as I go along. Do you have any suggestion for any action I could take as to solve this problem. Before I encountered the error, I used the flyCam to look at the environment I created, when I did try to create a player class that is what happened.

The problem is your variable is empty (null), it does not contain an actual object instance of the Player class, create a new instance and assign it to that variable. ← If you do not understand this sentence 100% thes not much use in going further from here, Java is an object oriented programming language, not a scripting language like PHP or Javascript.

This is what I have now. What specific variables are not being initialized or which instances are not being created, or am I missing the point completely. I did get rid of some of the code though to help me concentrate on making the camera work, which is what is giving me the trouble.

player.java:
[java]
package com.destroyerGames.aberration.characters;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.TouchInput;
import com.jme3.input.controls.*;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Node;

/**
@author Destroyer Games
/
public class Player {
/
*
creates instances of classes to use in the code.
/
private SimpleApplication application;
private Node rootNode;
private Camera cam;
private CameraNode camNode;
private FlyByCamera flyCam;
/
*
The states of the player. Defined by strings, and represented to the game
as decimal data values.
/
private int state = 0;
private static final int STATE_ALIVE = 0;
private static final int STATE_DEAD = 1;
private static final int STATE_ATTACKING = 2;
private static final int STATE_PUSHED = 3;
private static final int STATE_ATTACKED = 4;
private static final int STATE_SWINGING_SWORD = 5;
private static final int STATE_FIRING_SEMIAUTOMATIC_GUN = 6;
private static final int STATE_FIRING_AUTOMATIC_GUN = 7;
private static final int STATE_FIRING_BOW = 8;
private static final int STATE_RELOADING = 9;
private static final int STATE_WALKING = 10;
/
*
An idTag is a special identifier for a class that specifies which package
The UpdateManager will put the class in. In this case the
com.destroyerGames.aberration.characters’ special idTag is the number 2.
*/
public static final int idTag = 2;

/**
 Makes it compatible with SimpleApplication
 */
public Player(SimpleApplication application) {
    this.application = application;
}

/**
 Pulls everything together
 */
public void initPlayer() {
    fpCamera();   
}
/**
 Set up the first-person camera
 */
public void fpCamera() {
    rootNode = new Node();
    camNode = new CameraNode();
    flyCam = new FlyByCamera(cam);
    flyCam.setEnabled(true);
    flyCam.setMoveSpeed(2);
    application.getRootNode().attachChild(camNode);
}

}

[/java]

main.java
[java]
package com.destroyerGames.aberration;

import com.jme3.app.SimpleApplication;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.destroyerGames.aberration.characters.Player;
import com.jme3.scene.CameraNode;

public class Main extends SimpleApplication {
private SimpleApplication application;
private Player player;
private Spatial scene;

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

@Override
public void simpleInitApp() {
    scene = assetManager.loadModel("Scenes/somePlace.j3o");
    player = new Player(application);
    
    player.initPlayer();
    
    rootNode.attachChild(scene);
}

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

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

}
[/java]

and if the stack trace would be of use I will provide it here:
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.jme3.input.FlyByCamera.(FlyByCamera.java:95)
at com.destroyerGames.aberration.characters.Player.fpCamera(Player.java:72)
at com.destroyerGames.aberration.characters.Player.initPlayer(Player.java:64)
at com.destroyerGames.aberration.Main.simpleInitApp(Main.java:26)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:722)

Sorry if I am being difficult. I just gotta be more careful when I create the code so I do not run into this kind of problem again.

You never set this:
private Camera cam;

To anything. So you are passing a null to this:
flyCam = new FlyByCamera(cam);

Please do yourself a favor and go through some Java tutorials until you are really comfortable with the language. Writing games is advanced stuff. Writing 3D games is super-advanced stuff. Learning a language is advanced stuff. Doing all at once is jumping off a roof without a parachute and hoping to learn to fly on the way down.

Thanks for the advice, I will definately do so and try to get more comfortable with it. As for your solution, I know it should work, but the compiler keeps throwing me the same stupid error. I triple checked and as far as I could tell I created an instance for all the classes and the variables seem to be initialized correctly. I wonder if it could be that I’m forgetting to do something to make it work, or if the Engine itself is not working? Are there still some variables I have not initialized, or classes that are still null or have no instances created? It could be in the main class, but I have barely done anything to it that may cause it to throw the exception, and I am sure that unused imports shouldn’t cause the compiler to throw the exception. At this point I really have no other idea as to what might be causing the problem.

No. You did not understand. Pspeed is not giving you the solution, but the error !!!

  1. cam is null.
  2. you call FlyByCamera(cam)
  3. your FlyByCamera.setEnabled(true) throw the error because it uses your null cam.

You have to initialize variables before using them in Java : cam = application.getCamera();

I meant to say that even after I initialized cam it was still giving me the error, Which is what confused me in the first place.

@Destroyer said: I meant to say that even after I initialized cam it was still giving me the error, Which is what confused me in the first place.

Nope. It would not have given you the same error. You must have done something else wrong or were running different code.

NPEs are plain enough to figure out. The cam was null. If cam is not null then you will not get the same NPE.

That is true, it gave me a different stack trace. I just meant I was still getting an NPE. Here is the current stack trace:

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.destroyerGames.aberration.characters.Player.fpCamera(Player.java:66)
at com.destroyerGames.aberration.characters.Player.initPlayer(Player.java:60)
at com.destroyerGames.aberration.Main.simpleInitApp(Main.java:24)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:722)

and here is the code

player.java
[java]
package com.destroyerGames.aberration.characters;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.TouchInput;
import com.jme3.input.controls.*;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Node;

/**
@author Destroyer Games
/
public class Player {
/
*
creates instances of classes to use in the code.
/
private SimpleApplication application;
private Camera cam;
private CameraNode camNode;
private FlyByCamera flyCam;
/
*
The states of the player. Defined by strings, and represented to the game
as decimal data values.
/
private int state = 0;
private static final int STATE_ALIVE = 0;
private static final int STATE_DEAD = 1;
private static final int STATE_ATTACKING = 2;
private static final int STATE_PUSHED = 3;
private static final int STATE_ATTACKED = 4;
private static final int STATE_SWINGING_SWORD = 5;
private static final int STATE_FIRING_SEMIAUTOMATIC_GUN = 6;
private static final int STATE_FIRING_AUTOMATIC_GUN = 7;
private static final int STATE_FIRING_BOW = 8;
private static final int STATE_RELOADING = 9;
private static final int STATE_WALKING = 10;
/
*
An idTag is a special identifier for a class that specifies which package
The UpdateManager will put the class in. In this case the
com.destroyerGames.aberration.characters’ special idTag is the number 2.
*/
public static final int idTag = 2;

public Player(SimpleApplication application) {
this.application = application;
}

/**
 Pulls everything together
 */
public void initPlayer() {
    fpCamera();   
}
/**
 Set up the first-person camera
 */
public void fpCamera() {
    cam = application.getCamera();
    camNode = new CameraNode();
    flyCam = new FlyByCamera(cam);
    flyCam.setEnabled(true);
    flyCam.setMoveSpeed(2);
    application.getRootNode().attachChild(camNode);
}

}
[/java]

main.java
[java]
package com.destroyerGames.aberration;

import com.destroyerGames.aberration.characters.Player;
import com.jme3.app.SimpleApplication;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Spatial;

public class Main extends SimpleApplication {
private SimpleApplication application;
private Player player;
private Spatial scene;

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

@Override
public void simpleInitApp() {
    scene = assetManager.loadModel("Scenes/somePlace.j3o");
    player = new Player(application);
    
    player.initPlayer();
    
    rootNode.attachChild(scene);
}

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

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

}
[/java]

Now you never set application in SimpleApplication.

You should really learn to use Java before writing a Java game. Seriously. NPEs are the single easiest bugs to track down… like 100x easier than any other bug you will have. If you struggle with these, every other error you encounter will be 100 times harder to track down.

1 Like

SimpleApplication is abstract and cannot be instatiated, at least that is what jME is telling me. do I just set application to something else instead of creating a new instance of SimpleApplication almost like cam = application.getCamera; cam was not set to cam = new Camera; so could I do the same with SimpleApplication, and if so, what would I set it to. Afterward, if possible, could you point me to some good ebooks on java or possibly some good tutorials on the internet.

This is super-duper basic stuff. Never mind the fact that you don’t even need the application reference in the first place since ā€œthisā€ will be the same thing anywhere in that class.
[java]player = new Player(this);[/java]

re: learning Java. I don’t know. I learned it more than a decade ago.

http://www.javabeginner.com/

…is a common recommendation.

We try not to be a Java support forum here… yet here we are neck deep in it again. :wink:

Well, if you are already experienced in programming, you could also take a look at Thinking In Java.
3rd edition is available free of charge, but 4th is to be ordered.

Thanks, that finally got rid of the error. Time to learn more about the language. I do have a simple understanding of programming when I used Game Maker with its built in scripting language, but that is WAY different from java. After I get more comfortable with java itself, I might take a look at NiftyGui. Now I at least have a better understanding of NPE’s and am better equipped to handle them in the future.

GameMaker is nothing like java, you can create variables without initialing it and it would not be null, gm has objects, in java they are more or less represented as class, but a class is customizable and gm isn’t. Gm is great for games but when it comes to 3D i suggest using something else because you have to code every bit of code in gm to make 3D physics and more. I suggest thenewboston java tutorials that are on you tube, they cover the main topics of java.

Java is a programming language, like C, C++ or Obj-C. The others are scripting languages, its as simple as that :slight_smile: This is part of the reason why jME is way more powerful than the mentioned tools, plus you have the whole source code :wink:
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or theres an increased use of exclamation marks and all-capital words.