Hey monkeys,
I’m not certain if this one is graphic related or not, so plz forgive me if it’s not.
In my game which extends Application rather than SimpleApplication the update method looks like this.
[java]@Override
public void update() {
super.update();
try {
float tpf = timer.getTimePerFrame() * speed;
stateManager.update(tpf);
rootNode.updateLogicalState(tpf);
guiNode.updateLogicalState(tpf);
rootNode.updateGeometricState(); // throws exception
guiNode.updateGeometricState();
stateManager.render(renderManager);
renderManager.render(tpf);
stateManager.postRender();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}[/java]
So nothing special here.
The problem is the commented line throws an exception but the message just says null, not NullPointerException or anything alike. In the output it’s a single line with just the word null. Strangely it’s only thrown from time to time. So I’m wondering what exactly is the problem. It’s really hard to track down where it comes from. I guess there is some messed up node attached to the rootNode, or could it also be a control? Would be nice to have a bit more Information on that exception.
thx
Zenon
Can you perhaps provide the entire log please?
If you’re using jMP/NetBeans, is the “null” printed in the color black or red?
Does the application stop working after you see this “null” printed out?
It’s printed in black in the jmp output and does not crash the application
Here is the log.
There is a small delay between the start of the game and the first message. Then another delay to the second.
25.01.2011 19:45:47 com.jme3.system.JmeSystem initialize
INFO: Running on jMonkey Engine 3 Alpha 0.6
25.01.2011 19:45:47 com.jme3.system.Natives extractNativeLibs
INFO: Extraction Directory #1: file:/C:/Dev/jmonkeyplatform/jmonkeyplatform/libs/
25.01.2011 19:45:47 com.jme3.system.Natives extractNativeLibs
INFO: Extraction Directory #2: C:UsersZenonjMonkeyProjectsGangliona
25.01.2011 19:45:47 com.jme3.system.Natives extractNativeLibs
INFO: Extraction Directory #3: C:UsersZenonjMonkeyProjectsGangliona
25.01.2011 19:45:47 com.jme3.system.lwjgl.LwjglAbstractDisplay run
INFO: Using LWJGL 2.5
25.01.2011 19:45:47 com.jme3.system.lwjgl.LwjglDisplay createContext
INFO: Selected display mode: 800 x 600 x 0 @0Hz
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: Display created.
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: Adapter: aticfx64
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: Driver Version: 8.17.10.1036
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: Vendor: ATI Technologies Inc.
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: OpenGL Version: 3.3.10061 Compatibility Profile Context
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: Renderer: ATI Radeon HD 4800 Series
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglAbstractDisplay initInThread
INFO: GLSL Ver: 3.30
25.01.2011 19:45:48 com.jme3.system.lwjgl.LwjglTimer
INFO: Timer resolution: 1000 ticks per second
25.01.2011 19:45:48 com.jme3.renderer.lwjgl.LwjglRenderer initialize
INFO: Caps: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, TextureMultisample, OpenGL20, OpenGL21, OpenGL30, OpenGL31, OpenGL32, ARBprogram, GLSL100, GLSL110, GLSL120, GLSL130, GLSL140, GLSL150, VertexTextureFetch, TextureArray, TextureBuffer, FloatTexture, FloatColorBuffer, FloatDepthBuffer, PackedFloatTexture, SharedExponentTexture, PackedFloatColorBuffer, TextureCompressionLATC, MeshInstancing, VertexBufferArray]
25.01.2011 19:45:48 com.jme3.asset.DesktopAssetManager
INFO: DesktopAssetManager created.
25.01.2011 19:45:48 com.jme3.renderer.Camera
INFO: Camera created (W: 800, H: 600)
25.01.2011 19:45:49 com.jme3.renderer.Camera
INFO: Camera created (W: 800, H: 600)
25.01.2011 19:45:49 com.jme3.input.lwjgl.LwjglMouseInput initialize
INFO: Mouse created.
25.01.2011 19:45:49 com.jme3.input.lwjgl.LwjglKeyInput initialize
INFO: Keyboard created.
25.01.2011 19:45:49 com.jme3.audio.lwjgl.LwjglAudioRenderer initialize
INFO: AudioRenderer supports 64 channels
25.01.2011 19:45:49 com.jme3.audio.lwjgl.LwjglAudioRenderer initialize
INFO: Audio effect extension version: 1.0
25.01.2011 19:45:49 com.jme3.audio.lwjgl.LwjglAudioRenderer initialize
INFO: Audio max auxilary sends: 2
25.01.2011 19:45:50 com.jme3.material.MaterialDef
INFO: Loaded material definition: Unshaded
25.01.2011 19:45:50 com.jme3.scene.Node attachChild
INFO: Child (BitmapFont) attached to this node (null)
25.01.2011 19:45:50 com.jme3.scene.Node attachChild
INFO: Child (null) attached to this node (Gui Node)
25.01.2011 19:45:50 com.jme3.material.MaterialDef
INFO: Loaded material definition: Default GUI
Now activating MainMenu …
Entering GameState MainMenu …
Setting up Nifty in MainMenu …
25.01.2011 19:45:50 de.lessvoid.nifty.Nifty loadFromFile
INFO: loadFromFile [Interface/MainMenu.xml]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.NiftyLoader loadNiftyXml
INFO: loading new nifty xml file with schemaId [nifty.nxs]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.NiftyLoader loadNiftyXml
INFO: loaded nifty xml file with schemaId [nifty.nxs] took [44 ms]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: debug out [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: resourceBundles [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerStyle [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerControlDefinition [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerEffect [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerSound [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerMusic [0]
25.01.2011 19:45:50 de.lessvoid.nifty.loaderv2.types.ScreenType create
INFO: internal prepare screen (MainMenuScreen) [4]
25.01.2011 19:45:51 com.jme3.scene.Node attachChild
INFO: Child (BitmapFont) attached to this node (null)
25.01.2011 19:45:51 de.lessvoid.nifty.loaderv2.types.ScreenType create
INFO: internal create screen (MainMenuScreen) [313]
25.01.2011 19:45:51 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: create Screens [359]
25.01.2011 19:45:51 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerPopup [0]
25.01.2011 19:45:51 de.lessvoid.nifty.Nifty loadFromFile
INFO: loadFromFile took [409]
25.01.2011 19:45:51 de.lessvoid.nifty.Nifty gotoScreen
INFO: gotoScreen [MainMenuScreen]
25.01.2011 19:45:51 de.lessvoid.nifty.Nifty gotoScreenInternal
INFO: gotoScreenInternal [MainMenuScreen]
25.01.2011 19:45:51 de.lessvoid.nifty.screen.Screen$StartScreenEndNotify perform
INFO: onStartScreen has ended
25.01.2011 19:45:51 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_VertexColor is not declared in shader.
25.01.2011 19:45:52 de.lessvoid.nifty.effects.EffectProcessor startEffect
INFO: starting effect [(Pulsate)]
Exiting GameState MainMenu …
Entering GameState Running …
25.01.2011 19:45:53 de.lessvoid.nifty.screen.Screen$EndScreenEndNotify perform
INFO: onEndScreen has ended
25.01.2011 19:45:53 com.jme3.material.MaterialDef
INFO: Loaded material definition: Phong Lighting
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Floor) attached to this node (Scenes/Tutorial-scene_node)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Floor-geom-1) attached to this node (Floor-ogremesh)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Floor-ogremesh) attached to this node (Floor-entity)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Floor-entity) attached to this node (Floor)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Bounds) attached to this node (Scenes/Tutorial-scene_node)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Bounds-geom-1) attached to this node (Volume_Bounds-ogremesh)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Bounds-ogremesh) attached to this node (Volume_Bounds-entity)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Bounds-entity) attached to this node (Volume_Bounds)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Player) attached to this node (Scenes/Tutorial-scene_node)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Player-geom-1) attached to this node (Player-ogremesh)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Player-ogremesh) attached to this node (Player-entity)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Player-entity) attached to this node (Player)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Goal) attached to this node (Scenes/Tutorial-scene_node)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Goal-geom-1) attached to this node (Volume_Goal-ogremesh)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Goal-ogremesh) attached to this node (Volume_Goal-entity)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Goal-entity) attached to this node (Volume_Goal)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Jump001) attached to this node (Scenes/Tutorial-scene_node)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Jump001-geom-1) attached to this node (Volume_Jump001-ogremesh)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Jump001-ogremesh) attached to this node (Volume_Jump001-entity)
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Volume_Jump001-entity) attached to this node (Volume_Jump001)
25.01.2011 19:45:53 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:45:53 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:45:53 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:45:53 com.jme3.scene.Node attachChild
INFO: Child (Scenes/Tutorial-scene_node) attached to this node (Root Node)
New Player …
Loading playerObjects …
Setting up physics …
Setting up cam …
Initializing player controls …
warning CollisionDispatcher.needsCollision: static-static collision!
25.01.2011 19:45:53 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_Shininess is not declared in shader.
25.01.2011 19:45:53 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_UseMaterialColors is not declared in shader.
25.01.2011 19:45:53 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_Specular is not declared in shader.
25.01.2011 19:45:54 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_UseMaterialColors is not declared in shader.
25.01.2011 19:45:54 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_Ambient is not declared in shader.
Starting game in 3 seconds …
Starting game in 2 seconds …
Starting game in 1 seconds …
null
null
Reached the goal …
Cleaning up …
Poping GameStateRunning …
Exiting GameState Running …
Cleaning up unused triggers …
Now activating MainMenu …
Entering GameState MainMenu …
Setting up Nifty in MainMenu …
25.01.2011 19:46:09 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:46:09 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:46:09 com.jme3.scene.Node detachChildAt
INFO: Child removed.
25.01.2011 19:46:09 com.jme3.scene.Node detachAllChildren
INFO: All children removed.
25.01.2011 19:46:09 de.lessvoid.nifty.Nifty loadFromFile
INFO: loadFromFile [Interface/MainMenu.xml]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.NiftyLoader loadNiftyXml
INFO: loading new nifty xml file with schemaId [nifty.nxs]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.NiftyLoader loadNiftyXml
INFO: loaded nifty xml file with schemaId [nifty.nxs] took [9 ms]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: debug out [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: resourceBundles [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerStyle [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerControlDefinition [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerEffect [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerSound [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerMusic [0]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.ScreenType create
INFO: internal prepare screen (MainMenuScreen) [1]
25.01.2011 19:46:09 com.jme3.scene.Node attachChild
INFO: Child (BitmapFont) attached to this node (null)
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.ScreenType create
INFO: internal create screen (MainMenuScreen) [15]
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: create Screens [18]
null
25.01.2011 19:46:09 de.lessvoid.nifty.loaderv2.types.NiftyType create
INFO: registerPopup [0]
25.01.2011 19:46:09 de.lessvoid.nifty.Nifty loadFromFile
INFO: loadFromFile took [34]
25.01.2011 19:46:09 de.lessvoid.nifty.Nifty gotoScreen
INFO: gotoScreen [MainMenuScreen]
25.01.2011 19:46:09 de.lessvoid.nifty.Nifty gotoScreenInternal
INFO: gotoScreenInternal [MainMenuScreen]
25.01.2011 19:46:09 de.lessvoid.nifty.screen.Screen$StartScreenEndNotify perform
INFO: onStartScreen has ended
25.01.2011 19:46:10 de.lessvoid.nifty.effects.EffectProcessor startEffect
INFO: starting effect [(Pulsate)]
Cleaning up …
Poping GameStateMainMenu …
Exiting GameState MainMenu …
25.01.2011 19:46:10 com.jme3.input.lwjgl.LwjglMouseInput destroy
INFO: Mouse destroyed.
25.01.2011 19:46:10 com.jme3.input.lwjgl.LwjglKeyInput destroy
INFO: Keyboard destroyed.
25.01.2011 19:46:10 com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread
INFO: Display destroyed.
BUILD SUCCESSFUL (total time: 25 seconds)
I think i found where it is raised. Looks like it comes from a concurrent access to the list in the controlUpdate method here.
[java]
public class TriggerSystem extends AbstractControl {
private List<Trigger> triggers = Collections.synchronizedList(new LinkedList<Trigger>());
public TriggerSystem() {}
public void enabled(boolean enable) { this.setEnabled(enabled); }
public void registerTrigger(Trigger trigger) { triggers.add(trigger); }
public void markAllUnused() {
ListIterator iterator = triggers.listIterator();
while (iterator.hasNext())
((Trigger) iterator.next()).markForRemoval();
}
public void removeUnused() {
System.out.println("Cleaning up unused triggers …");
try {
ListIterator iterator = triggers.listIterator();
while (iterator.hasNext()) {
if (((Trigger) iterator.next()).isUnused()) iterator.remove();
}
} catch (Exception ex) {
System.out.println("WHILE REMOVING TRIGGERS: "+ex.getMessage());
}
}
@Override
protected void controlUpdate(float tpf) {
try {
if (!removing) {
for (Trigger trigger : triggers) {
if (!trigger.isUnused() && trigger.getCondition().holds(tpf)) {
trigger.getReaction().react(tpf);
}
}
}
}catch (Exception ex) {
System.out.println("WHILE PROCESSING TRIGGERS: "+ex.getMessage());
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) { }
public Control cloneForSpatial(Spatial spatial) { return this; }
}
[/java]
Odd that the most important control in the game came last to my mind but i thought I would prevent such behaviour by disabling it prior to calling the removeUnused() method and then enabling it again and making the list synchronized.
I assume you mean the message is printed from your code? I don’t see anything in your control implementation that could print null
That’s because I added the try-catch after the run from the previous log.
The output now looks like this.
WHILE PROCESSING TRIGGERS: null
Maybe there is some trigger still active (being processed) while I call removeUnused.
Would that prevent the Control from being disabled?
Just do ex.printStackTrace()
Got it.
It really was a concurrent access and not a null pointer exception.
There has been a trigger which re-initialized my trigger-remover which in turn calls removeUnused.
I’m feeling a bit embarrassed right now and gonna move the timer to remove the triggers into the triggersystem itself for safety.
Thx for guiding me through.