Adding pointlight to rootnode from outside simpleapp

Okey, very confused about this error. I’m getting a ‘null point exception’ and then the program, crashes, burns and dies!

I’m trying to add various ‘lamps’ around the environment which the user can turn on and off (thus they effect the environment and should be added to rootNode…right?)

It works if I call it from the ‘main app’ like so:

[java] public void addPointLight(Vector3f location, String name) {
PointLight p = new PointLight();
p.setPosition(location);
p.setRadius(30f);
p.setName(name);
rootNode.addLight§;
}[/java]

However, when I add it from another class, like so:
[java] public void addPointLight(Vector3f location, String name) {
PointLight p = new PointLight();
p.setPosition(location);
p.setRadius(30f);
p.setName(name);
app.getRootNode().addLight§;
}[/java]

Spits out errors which arn’t particually helpful and just say ‘Null pointer exception’. I checked both ‘app.getRootNode’ and ‘p’ for being null, and they were not. So I literally has no ideas!

I could of course do app.addPointLight blahblah. But i’m curious as to why the app.getRootNode.addLight isn’t working?
EDIT: Actually no I can’t do the above app.addPointLight…erm… :S :S :S

Any possible ideas? :).

Thankyou :).

when you cant call you own function, then there is something not set up correctly. Are u shure that you call it from the correct context? Has JME3 already called its SimpleApplicationInit-fn? Is your Main-Object initiallized and are you calling it from inside or are you perhaps in statical main(argv[]…)-context?

what happens, when u put a line-breakpoint at this line:
app.getRootNode().addLight§;
and then trace the programm? At wich point do you get the exeption?

@rhavin said: when you cant call you own function, then there is something not set up correctly. Are u shure that you call it from the correct context? Has JME3 already called its SimpleApplicationInit-fn? Is your Main-Object initiallized and are you calling it from inside or are you perhaps in statical main(argv[]…)-context?

what happens, when u put a line-breakpoint at this line:
app.getRootNode().addLight(p);
and then trace the programm? At wich point do you get the exeption?

Hey, thanks for the reply there. Lots of useful questions.

When I put a break there and step-over I get the error. However it provided a little more information:

[java]Feb 24, 2013 3:27:25 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at mygame.HouseScene.setupModels(HouseScene.java:37)
at mygame.Scene.(Scene.java:40)
at mygame.HouseScene.(HouseScene.java:22)
at mygame.Main.simpleInitApp(Main.java:60)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
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)[/java]

[java] public HouseScene(String houseScene, Main app) {
super(houseScene, app);
}

@Override
public void setupModels() {
    Node lamp = (Node)models.get("Floor lamp");
    System.out.println("Lamp found " + lamp + " Location " + lamp.getWorldTranslation());
    
    if(lamp != null) {           
        // this causes the error
        app.addPointLight(lamp.getWorldTranslation(), lamp.getName());
    
    } else {
        System.out.println("Point light not found");
    }      
}[/java]

[java]
Code in the Main class (app)
public void addPointLight(Vector3f location, String name) {
PointLight p = new PointLight();
p.setPosition(location);
p.setRadius(30f);
p.setName(name);
rootNode.addLight(p);
} [/java]

It basically goes and finds the lamp models and is meant to attach a light to the rootnode for it. The ‘Node lamp’ is definately not null, I’ve been able to add controls to it and manipulate the material on it.

OH FFS. Just found the problem, was missing a bloody this.app = app; in the constructor. Lmao. Don’t quite know why getRootNode wasn’t returning null therefore but it’s working now. Thanks so much! Teaches me to be coding at 4am haha…

Its always wise to initialize all pointers (i can hear the java-gods grumble at the forbidden word :D) to null to stop that from happen :slight_smile:

@rhavin said: Its always wise to initialize all pointers (i can hear the java-gods grumble at the forbidden word :D) to null to stop that from happen :)
:?

@normen: i dont know what Java-versions this does happen to, but compared to msvc, where unitialized pointers are in fact initialized to protected memory 0xcccccccc and do immedialty segfault at usage in debug and to 0x00000000 in production - where they still segfault - i’ve noticed (twas about 2 years ago, dont know if this still happens) and im not at home to check this), that the JVM does set something like…

[java]
private SomeObject foo;
[/java]

…not to null, but just allocates the heap for it and and leaves it to any value at all, so a call to a method that just returns another pointer and is therefore inlined and thats not already setup to a reference passes unchecked. Cant check that now for my actual JVM but i since then i always set up pointers that are not pointing to a reference (that was the correct and technically more reasonable term before the marketing devision decided that “java has no pointers”) to null.

Actually the java compiler won’t let you compile code where you would directly access an uninitialized variable. But even if you somehow manage to its just the good ol’ java “null”.
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 there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

Comforting :-› … Then everybody please see my last advice on that just as an innoxious old habbit.

@Normen : I think you’re wrong there. Well. Not totally right…
In java, you cannot use LOCAL uninitialized variables. But you can used uninitialized fields. In this case, they are filled with 0 / null.

@yang71 said: @Normen : I think you're wrong there. Well. Not totally right... In java, you cannot use LOCAL uninitialized variables. But you can used uninitialized fields. In this case, they are filled with 0 / null.
Yeah, like I said its basically not possible to run into a situation where a variable not set to null manually causes issues as they are automatically null if you can access them. Maybe I put it a bit convoluted. Its true that you probably can't even manage to access uninitialized variables in the local scope and that fields are always inited to null and don't cause any compiler issues. 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 there's emotes that hint otherwise or there's an increased use of exclamation marks and all-capital words.
@yang71 said: @Normen : I think you're wrong there. Well. Not totally right... In java, you cannot use LOCAL uninitialized variables. But you can used uninitialized fields. In this case, they are filled with 0 / null.

They are initialized. That’s the point. The Java spec says that object fields are always initialized. If you don’t initialize them yourself then they are initialized to default values. null in the case of object references.

Local variables are not automatically initialized because they are stack variables and because automatically initializing them is wasteful.

It’s funny… the SDK will even warn you when you initially a local variable and didn’t need to.

[java]Object someObject = null;
if( foo ) {
someObject = bar;
} else {
someObject = baz;
}[/java]

The SDK puts a little yellow bulb on the first line telling you the assigned value is never used or some such.

@pspeed said: The SDK puts a little yellow bulb on the first line telling you the assigned value is never used or some such.

To be honest: i always thought this the totally wrong direction this “warning” (just in case of null!) is pushing programmers. While it may be true, that not assigning a value to a ref initializes it with null, there is always the benefit of having clearer code w/o any additional ops when manually assigning them to null.

I personally just ignore this warning always and the snipped you posted is exactly how i do it. The only case where i’d consider not doing it would be a routine that i know is happen to get called very often. In all other cases: rubustness and clearity supersedes 1-op-performance, but in those cases, my java looks already like java’d assembler.

@rhavin said: To be honest: i always thought this the totally wrong direction this "warning" (just in case of null!) is pushing programmers. While it may be true, that not assigning a value to a ref initializes it with null, there is always the benefit of having clearer code w/o any additional ops when manually assigning them to null.

I personally just ignore this warning always and the snipped you posted is exactly how i do it. The only case where i’d consider not doing it would be a routine that i know is happen to get called very often. In all other cases: rubustness and clearity supersedes 1-op-performance, but in those cases, my java looks already like java’d assembler.


I’d consider a rule where the application has to be revised each time inferior to one that always works :wink: As said, java will not let you compile anyway if theres “danger”. But generally I concur, the compiler is much, much, much more able to optimize your code than you are, especially if you write your code clean and readable and don’t try to “optimize” yourself.
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 there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

Nope, compiler doesnt for example know what kind of precision you need. Changing some floats to ints afterwards multipicating them with 100, doing your calc xyz times (may be quite a lot!) with int-arithmetric and then finally deviding it by 100 after reassigning them to float helped me in a scenario where i had to increase performance a lot. But i agree that those a re very special cases.

Yeah, in that case you have very special knowledge that you don’t need any great precision and that you are not going to overflow. That’s very special-case knowledge though and in fact suggests that floats was the wrong data type in the first place and it should always be int*100…

@rhavin said: To be honest: i always thought this the totally wrong direction this "warning" (just in case of null!) is pushing programmers. While it may be true, that not assigning a value to a ref initializes it with null, there is always the benefit of having clearer code w/o any additional ops when manually assigning them to null.

I personally just ignore this warning always and the snipped you posted is exactly how i do it. The only case where i’d consider not doing it would be a routine that i know is happen to get called very often. In all other cases: rubustness and clearity supersedes 1-op-performance, but in those cases, my java looks already like java’d assembler.

In my example with local variables, it is a performance issue. You set the stack variable twice no matter which path the code takes… which is why presetting it to null is a warning in the SDK. It can also be a sign that your code is broken if you expected it to be otherwise. I understand it’s a small thing but there is 0 reason to put the null there. The compiler will tell you if you never set it properly. So you are doing extra work and adding code that just clutters things up for no reason. And everyone who reads your code will think you are a C coder that is just barely learning Java… which may be ok in this case.

To me the code is less clear because it’s doing something unnecessary and then I have to wonder if the original author meant it to do something different. Wandering into wild code, we cannot guess which of five different things were misunderstood in such a code block.

It’s similar to the folks who put parenthesis around every operation just to make sure they go in the order intended. Sometimes it’s ok to be safe but mostly it just looks like someone didn’t know operator precedence at all. x = ((a + (b * 2)) + (a + c)) * ((d *3) * 4) gah!

1 Like
@pspeed said: It can also be a sign that your code is broken if you expected it to be otherwise.
This. The little bulbs already kept so many small bugs out of jME ;) And not setting everything to null just tells you earlier ^^ 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 there's emotes that hint otherwise or there's an increased use of exclamation marks and all-capital words.
@zarch said: Yeah, in that case you have very special knowledge that you don't need any great precision and that you are not going to overflow. That's very special-case knowledge though and in fact suggests that floats was the wrong data type in the first place and it should always be int*100...

Fixed point for the win.

And remember, on x86 architectures for quite a while integer multiplication was slower than floating point multiplication… ever since FPUs were dedicated on-chip. Be careful how you try to fool hotspot.

@rhavin said: Its always wise to initialize all pointers (i can hear the java-gods grumble at the forbidden word :D) to null to stop that from happen :)

The problem was that it was null, so setting it to null wouldn’t have solved it :).

@normen said: This. The little bulbs already kept so many small bugs out of jME ;) And not setting everything to null just tells you earlier ^^ 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 there's emotes that hint otherwise or there's an increased use of exclamation marks and all-capital words.

Missed this comment before.

Yes. And this falls into the category of one of those “safety” things that does the opposite of what’s intended. At best it does nothing. At worst it hides a real bug, ie: it’s less safe. There are a few Java anti-idioms like this. My other favorite one is the “if( in != null ) in.close” try/catch anti-idiom.