SOLVED: Unbelievable NullpointerException

Hi,

I have a problem with a null pointer Exception. I have a method in my GameState. This method is called within the update()-method of the state with several parameters. Look at my update method:

@Override
    public void update(float tpf) {        
    updatePermeableFilter();
    updateVerticalForce(tpf);                        
    updatePlayerPosition(tpf);             
}

The method updatePlayerPosition() and updateVerticalForce() are calling

isUserInPermableBlock(Direction.TOP);

No problem. Works fine.

The method updatePermeableFilter() is calling

isUserInPermeableBlock(Direction.BOTTOM);

So, now let’s have a look at this method: (Yes, Direction.BOTTOM and Direction.TOP are int constants):

private boolean isUserInPermeableBlock(int direction) {
    Vector3f loc = m_player.getLocalTranslation().clone();
    if (direction == Direction.BOTTOM) {
        loc.y -= Player.PLAYER_HEIGHT;
    } else {
        loc.y -= (Player.PLAYER_HEIGHT / 4.0f);
    }
    return Block.isPermeable(m_world.getBlockAt(loc));        
}

In all ways, this method does not throw any exception but works fine. Even if I call it with the Paramater Direction.TOP. In this case, a new Quad with an unshaded material is created and put to the gui node.

Nothing like rocket science or so, but I got a NullPointerExcpetion:

java.lang.NullPointerException
at com.jme3.shader.Uniform.setValue(Uniform.java:184)
at com.jme3.material.Technique.updateUniformParam(Technique.java:151)
at com.jme3.material.MatParam.apply(MatParam.java:147)
at com.jme3.material.Material.render(Material.java:1088)
at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:523)
at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:322)
at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:371)
at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:788)
at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:719)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:983)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1035)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:252)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:744)

Normally I’d say that I made a mistake when adding the Quad to the gui node, but I don’t think so. If i delete the path for Direction.TOP in the above function usUserInPermableBlock(…), the quad is also set, just a little bittle later (if the player is deeper in the water). That means, the quad is set in qvery case, but if I have th little piece of code

loc.y -= (Player.PLAYER_HEIGHT / 4.0f);

than it won’t work and I get the exception.

Does anybody have an idea? Maybe it would also be helpfull if one of the core developers could tell me what the exception means (yes, something is null, I know, but what is interneally done, if the exception occurs? Seems to occur during rendering?!)

Post the line of code that gives you that exception, the line Uniform.java:184 , its not clear where it is.
If this is the Player.XXX probally Player is null, did you debug it to see what is null ?
Anyway, I dont think this have anything to do with the engine.

Hmmm… the exception occurs within jme: Uniform belongs to the package com.jme3.shader.

  public void setValue(VarType type, Object value){
      ...
      if (value == null) {
          throw new NullPointerException();
      }
      ...

The Player is not null, and also the localTranslation of th player is not null. The Exception is not thrown by my code. But I can avoid the exception if I change a piece of code that (maybe) nothing have to do with the code that throws the exception.

Did you check the parameters you are trying to apply to the material ?
If you try to apply an null color for example I guess you will have this error.

Sure I did :slight_smile: That is the kind of magic about this exception. The material works! The method that creates the quad and tha material is called in every case! Sooner or later. If I just delete theat little

loc.y -= (Player.PLAYER_HEIGHT / 4.0f);

from the method I mentioned above, it works. It I add this method, it does not work.

loc is a vector3f and it is a local variable of the method. And it is a CLONE of the players(Node) localTranslation. So, I really don’t understand this.

The only way that line could affect this is if it makes a Geometry visible that wasn’t visible before… or if you are doing something else somewhere conditionally on loc.y.

Else, one of your Material parameters is set to null. (Edit: not ‘else’… definitely one of your material parameters is set null I was just trying to explain why it might show or not because of that line.)

Unfortunately, the version of JME that you are running did the really dumb thing of throwing NullPointerException itself (HINT: never ever ever ever ever do this… .when in doubt… never ever ever ever do this. Never)… instead of throwing a more useful exception that might have included the parameter name.

Quickest way to debug this is to… run in the debugger and set a breakpoint where that NPE is thrown and then you can see what material parameter you’ve set to null.

:frowning: Okay, I am guilty! Very guilty! @pspeed : you were right: a new geometry is shown in that case and it’s color was null. Just because the method that creates the new material checks again in which “block” the user is, but the material creating method did not subtract 1/4 of the players height from the y location.

The result is that the method isUserInPermeableBlock thinks the user is in water and after that the method for creating a quad is called. The quad material again gets the block the user is in, but it receives a block that is a little bit above the user (1/4 of its size). Then the needed color is requestes from my Blockmanager and that returns null, because the block ABOVE the user is air and do not have any color.

So, you’re all right! I’m so guilty that I really feel ashamed :frowning:

Thanks for your help.

Glad you found the issue.

Part of the trick of debugging is separating the things you believe to be true from the things that actually are true.

Modesty aside, debugging is one of my “super powers”… but it’s no trick, really. Hold diligently to the facts, cast aside the super-natural, validate assumptions. Repeat as needed.

In this case, the starting fact was your stack trace and generally it cannot and will not lie. So that is the basic fact that all further evidence must be built upon. When if( value == null ) is executing its block then you can 100% guarantee that value == null and work backwards.

Now, if you’d started there you would have fixed your problem very quickly… though you then might not know why that one line inclusion/exclusion fixed the issue. That probably would have been fun to figure out on your own. :smile: But solving those kinds of puzzles is what will give you debugging super-powers.

Edit: ie: going beyond solving the problem and trying to fully understand the problem. The best kind of puzzles are the ones that can suck up your whole life. :slight_smile:

This is a very wise sentence which does not only is true for debugging :smile:

To be honest: Debugging is not my super power but my Kryptonit :slight_smile: Sure, it’s no problem to solve little puzzles that are based on source code of my own. But I’m always confused when an excpetion is thrown by a library or framework from deep inside. I know I should not be afraid of debugging other code than my own - but I am :frowning:

However: your words made me think about this and next time I’ll try to pay respect to them :slight_smile: Thank you again.

Never be afraid to look into the source of an open source project. It will always be extremely educational… even if it turns out to be a good example of a bad example. (throw new NullPointerException(), indeed.)

It’s like if you were learning a musical instrument and only ever played your own music. You learn so much more raw technique by playing other peoples’ music.